Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Praktische Anwendungen (Showcase)
  4. Vorstellung: e-Ink display für Hausstatus

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.7k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.1k

Vorstellung: e-Ink display für Hausstatus

Geplant Angeheftet Gesperrt Verschoben Praktische Anwendungen (Showcase)
5 Beiträge 4 Kommentatoren 6.3k Aufrufe 8 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • L Offline
    L Offline
    lxs
    schrieb am zuletzt editiert von
    #1

    Hallo,

    Ich würde euch gerne mein kleines Projekt vorstellen. Ich habe mir ein Display gebaut, welches ich an der Haustüre innen verbauen will, so dass ich auf einen Blick sehe ob z.B. noch Fenster offen sind. Ausserdem habe ich gleich noch eine Anwesenheitserkennung mit aufgebaut.

    Eingesetzt habe ich:

    • Olimex ESP32-POE-ISO Board: Bluetooth Low Energy Scanner und Ansteuerung für das Display
    • Waveshare 400x300, 4.2inch E-Ink raw display (Artikelnr. 13186)
    • Waveshare 4.2inch e-Paper Raw Panel Case (Artikelnr. 16116
    • Waveshare Universal e-Paper Raw Panel Driver HAT (Artikelnr 13512)
    • Gigaset G-Tag Bluetooth Low Energy beacons

    Das Setup ist folgendes:

    Das ESP32 Board habe ich mit ESPHome programmiert. Die Verbindung zum iobroker geht über mqtt. Das ESP32 Board wird über POE mit Strom und LAN versorgt. Am Ende wird das in eine Unterputz-Installationsdose versenkt und das Display auf einer Blindabdeckung auf dem Schalterrahmen befestigt.

    Hier der relevante Code:

    Die yaml-Datei für ESPhome:

    esphome:
      name: bt_eingang
      platform: ESP32
      board: esp32-poe-iso
    
    ethernet:
      type: LAN8720
      mdc_pin: GPIO23
      mdio_pin: GPIO18
      clk_mode: GPIO17_OUT
      phy_addr: 0
      power_pin: GPIO12
      
    font:
      - file: "ubuntu.ttf"
        id: my_font
        size: 20
    spi:
      clk_pin: 14
      mosi_pin: 4
      
    
    esp32_ble_tracker:
    
    binary_sensor:
      - platform: ble_presence
        mac_address: 58:9E:XX:XX:XX:XX
        name: "Tracker white"
        id: track_w
      - platform: ble_presence
        mac_address: 58:9E:XX:XX:XX:XX
        name: "Tracker black"
        id: track_b
    
    text_sensor:
      - platform: mqtt_subscribe
        name: "Aussentemperatur"
        id: temp_out
        topic: bt_eingang/display/temp_out
      - platform: mqtt_subscribe
        name: "Headline"
        id: fc_symbol
        topic: bt_eingang/display/headline
      - platform: mqtt_subscribe
        name: "Line 2OG Licht"
        id: line_2OG_licht
        topic: bt_eingang/display/line_2OG_licht
      - platform: mqtt_subscribe
        name: "Line 2OG Fenster"
        id: line_2OG_fenster
        topic: bt_eingang/display/line_2OG_fenster
      - platform: mqtt_subscribe
        name: "Line 1OG Licht"
        id: line_1OG_licht
        topic: bt_eingang/display/line_1OG_licht
      - platform: mqtt_subscribe
        name: "Line 1OG Fenster"
        id: line_1OG_fenster
        topic: bt_eingang/display/line_1OG_fenster
      - platform: mqtt_subscribe
        name: "Line EG Fenster"
        id: line_EG_fenster
        topic: bt_eingang/display/line_EG_fenster
      - platform: mqtt_subscribe
        name: "Line EG Licht"
        id: line_EG_licht
        topic: bt_eingang/display/line_EG_licht    
      - platform: mqtt_subscribe
        name: "Anwesenheit"
        id: presence_string
        topic: bt_eingang/display/presence_string
    
    #Bilder aus dem DasWetter-Adapter invertiert und als jpg ohne Transparenz gespeichert
    
    image:
      - file: "icons/tiempo-weather/galeria5/PNG/mine/1.jpg"
        id: image_1
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/2.jpg"
        id: image_2
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/3.jpg"
        id: image_3
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/4.jpg"
        id: image_4
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/5.jpg"
        id: image_5
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/6.jpg"
        id: image_6
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/7.jpg"
        id: image_7
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/8.jpg"
        id: image_8
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/9.jpg"
        id: image_9
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/10.jpg"
        id: image_10
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/11.jpg"
        id: image_11
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/12.jpg"
        id: image_12
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/13.jpg"
        id: image_13
        resize: 60x60
      - file: "icons/tiempo-weather/galeria5/PNG/mine/14.jpg"
        id: image_14
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/15.jpg"
        id: image_15
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/16.jpg"
        id: image_16
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/17.jpg"
        id: image_17
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/18.jpg"
        id: image_18
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/19.jpg"
        id: image_19
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/20.jpg"
        id: image_20
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/21.jpg"
        id: image_21
        resize: 40x40
      - file: "icons/tiempo-weather/galeria5/PNG/mine/22.jpg"
        id: image_22
        resize: 40x40
     
    
    display:
      - platform: waveshare_epaper
        cs_pin: 16
        dc_pin: 15
        busy_pin: 13
        reset_pin: 2
        model: 4.20in
        update_interval: 3600s  #Displayrefresh flickert bei dem Display leider
        id: my_display
        lambda: |-
          it.printf(10,20, id(my_font), "Temperatur: %s", id(temp_out).state.c_str());
          it.print(250,10, id(my_font), "Vorhersage:");
          if (id(fc_symbol).state == "1") { it.image(360, 0, id(image_1)); };
          if (id(fc_symbol).state == "2") { it.image(360, 0, id(image_2)); };
          if (id(fc_symbol).state == "3") { it.image(360, 0, id(image_3)); };
          if (id(fc_symbol).state == "4") { it.image(360, 0, id(image_4)); };
          if (id(fc_symbol).state == "5") { it.image(360, 0, id(image_5)); };
          if (id(fc_symbol).state == "6") { it.image(360, 0, id(image_6)); };
          if (id(fc_symbol).state == "7") { it.image(360, 0, id(image_7)); };
          if (id(fc_symbol).state == "8") { it.image(360, 0, id(image_8)); };
          if (id(fc_symbol).state == "9") { it.image(360, 0, id(image_9)); };
          if (id(fc_symbol).state == "10") { it.image(360, 0, id(image_10)); };
          if (id(fc_symbol).state == "11") { it.image(360, 0, id(image_11)); };
          if (id(fc_symbol).state == "12") { it.image(360, 0, id(image_12)); };
          if (id(fc_symbol).state == "13") { it.image(360, 0, id(image_13)); };
          if (id(fc_symbol).state == "14") { it.image(360, 0, id(image_14)); };
          if (id(fc_symbol).state == "15") { it.image(360, 0, id(image_15)); };
          if (id(fc_symbol).state == "16") { it.image(360, 0, id(image_16)); };
          if (id(fc_symbol).state == "17") { it.image(360, 0, id(image_17)); };
          if (id(fc_symbol).state == "18") { it.image(360, 0, id(image_18)); };
          if (id(fc_symbol).state == "19") { it.image(360, 0, id(image_19)); };
          if (id(fc_symbol).state == "20") { it.image(360, 0, id(image_20)); };
          if (id(fc_symbol).state == "21") { it.image(360, 0, id(image_21)); };
          if (id(fc_symbol).state == "22") { it.image(360, 0, id(image_22)); };
         //geht sicher auch schöner in einer Zeile Code...
          it.line(0, 47, 400, 47);
          //Table
          it.line(100, 110, 300, 110); 
          it.line(100, 150, 300, 150);
          it.line(100, 190, 300, 190); 
          it.line(100, 230, 300, 230);
          it.line(200, 110, 200, 230);
          it.line(100, 110, 100, 230);
          it.line(300, 110, 300, 230);
          //Lastline
          it.line(0, 255, 400, 255);
          it.print(130,80,id(my_font), "Licht");
          it.print(220,80,id(my_font), "Fenster");
          it.print(50,120,id(my_font), "2 OG");
          it.print(50,160,id(my_font), "1 OG");
          it.print(70,200,id(my_font), "EG");
          it.printf(110,130, id(my_font), "%s", id(line_2OG_licht).state.c_str());
          it.printf(210,130, id(my_font), "%s", id(line_2OG_fenster).state.c_str());
          it.printf(110,170, id(my_font), "%s", id(line_1OG_licht).state.c_str());
          it.printf(210,170, id(my_font), "%s", id(line_1OG_fenster).state.c_str());
          it.printf(110,210, id(my_font), "%s", id(line_EG_licht).state.c_str());
          it.printf(210,210, id(my_font), "%s", id(line_EG_fenster).state.c_str());
          it.printf(10,275,id(my_font), "Anwesenheit: %s", id(presence_string).state.c_str());
    
    
    # Enable logging
    logger:
    mqtt:
      broker: #IP vom iobroker
      username: #wie in iobroker mqtt adapter
      password: #wie in iobroker mqtt adapter
      client_id: bt_Eingang
    #  log_topic: bt_eingang/log/
      on_message: # Manueller refresh des Displays bei Änderung
        topic: bt_eingang/display/refresh
        payload: "ON"
        then:
          - component.update: my_display
          
    ota:
    

    Das spannende (aber dann doch triviale - man kann hier recht frei entscheiden) war hier die HW Verkabelung. Diese ist im yaml dokumentiert. die GPIO Pins stehen im Plan auf der Olimex-Seite.

    Auf dem iobroker habe ich ein Javascript um per mqtt die entsprechenden Werte zu liefern:

    var fenster1OG=['hm-rpc.3.0000XXXXXXXXXX.1.STATE'/*Fensterkontakt Schlafzimmer:1 STATE*/, 
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Balko Arbeitszimmer:1 STATE*/,
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster KiZi:1 STATE*/,
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Bad 1OG STATE*/,
    'hm-rpc.0.MEQ02XXXXX.1.STATE'/*Fenster Fenster AZ STATE*/];
    
    var fenster2OG=['hm-rpc.0.JEQ0XXXXXX.1.STATE'/*Fenster Dach Nord:1 STATE*/,
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Küche STATE*/,
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Gaube STATE*/,
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Fenster West:1 STATE*/,
    'hm-rpc.0.KEQ01XXXXX.1.STATE'/*Fenster Badewanne:1 STATE*/,
    'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Bad 2OG:1 STATE*/];
    
    var presence=['javascript.1.presence_black'/*presence black*/,'javascript.1.presence_white'/*javascript 1 presence white*/]; //u.a. aus den Werten des BLE Scanners ermittler, aber noch aus einem zweiten Scanner und mit einer Hysterese
    
    on({id:'hm-rega.0.XXX'/*Licht 1OG*/, change: "ne"}, function(obj) { //Variable fürs Licht wird bei mir in der CCU gepflegt.
       var output;
       var input=obj.state.val;
       if (input) {
           output="An";
       } else {
           output="Aus";
       };
       setState('mqtt.0.bt_eingang.display.line_1OG_licht'/*bt eingang/display/line 1OG licht*/,output);
       redraw_display();
    });
    
    on({id:'hm-rega.0.1XXX'/*Licht2OG*/, change: "ne"}, function(obj) {
       var output;
       var input=obj.state.val;
       if (input) {
           output="An";
       } else {
           output="Aus";
       };
       setState('mqtt.0.bt_eingang.display.line_2OG_licht'/*bt eingang/display/line 1OG licht*/,output);
       redraw_display();
    });
    
    on({id:presence, change: "ne"}, function(obj) {
       var output="";
       if (getState("javascript.1.presence_black").val){
           output = output +"Schwarz "; //Hier kann man die Namen der Besitzer eintragen
       };
       if (getState("javascript.1.presence_white").val) {
           output = output + "Weiss ";
       };
       setState('mqtt.0.bt_eingang.display.presence_string'/*bt eingang/display/presence string*/,output);
       redraw_display();
    }); 
    
    on({id:fenster1OG, change: "ne"}, function(obj) {
       var output;
       var input=obj.state.val;
       var open_1OG=0;
       var gekippt_1OG=0;
       var closed_1OG=0;
       for (var i = 0; i < fenster1OG.length; i++) {
           var ws = getState(fenster1OG[i]).val;
           if (fenster1OG[i]=="hm-rpc.3.0000DXXXXXXX.1.STATE") {  //Fensterkontakt mit nur zwei Zuständen
               if (ws==0) {
                   closed_1OG++;
               } else if (ws==1) {
                   open_1OG++;
               };
           } else {   //Normalerweise habe ich Griffsensoren mit 3 Zuständen
               if (ws==0) {
                   closed_1OG++;
               } else if (ws==1) {
                   gekippt_1OG++;
               } else if (ws==2) {
                   open_1OG++;
               }
           };
       };
       output = windowstring(open_1OG,gekippt_1OG,closed_1OG);
       setState('mqtt.0.bt_eingang.display.line_1OG_fenster'/*bt eingang/display/line 1OG fenster*/,output);
       redraw_display();
    });
    
    on({id:fenster2OG, change: "ne"}, function(obj) {
       var output;
       var input=obj.state.val;
       var open_2OG=0;
       var gekippt_2OG=0;
       var closed_2OG=0;
       for (var i = 0; i < fenster2OG.length; i++) {
           var ws = getState(fenster2OG[i]).val;
        
           if (fenster2OG[i]=="hm-rpc.3.000XXXXXX1.STATE") { 
               if (ws==0) {
                   closed_2OG++;
               } else if (ws==1) {
                   open_2OG++;
               };
           } else {
               if (ws==0) {
                   closed_2OG++;
               } else if (ws==1) {
                   gekippt_2OG++;
               } else if (ws==2) {
                   open_2OG++;
               }
           };
       };
       output = windowstring(open_2OG,gekippt_2OG,closed_2OG);
       setState('mqtt.0.bt_eingang.display.line_2OG_fenster'/*bt eingang/display/line 1OG fenster*/,output);
       redraw_display();
    });
    
    on({id:'netatmo.0.XXXX.XXX.Temperature.Temperature'/*Temperature*/, change: "ne"}, function(obj) {
       setState('mqtt.0.bt_eingang.display.temp_out'/*bt eingang/display/temp out*/,obj.state.val);
    }); //Aussentemperatur. Änderung macht kein Display-Refresh, da das e-ink ca. 2-3 Sekunden beim aktualisieren flackert. Wird bei der nächsten Änderung oder nach 3600s wie im esphome-Skript aktualisiert. 
    
    on({id:"daswetter.0.NextHours.Location_1.Day_1.in1hours.symbol_value", change:"ne"}, function(obj){
       setState('mqtt.0.bt_eingang.display.headline'/*bt eingang/display/headline*/,obj.state.val);
       redraw_display();
    }); //Forecast für die nächste Stunde. 
    
    
    function redraw_display() {
       setState('mqtt.0.bt_eingang.display.refresh'/*bt eingang/display/refresh*/,"ON");
       setStateDelayed('mqtt.0.bt_eingang.display.refresh', "OFF",  1000);    
    }; //mit "ON" wird das Display aktualisiert. 
    
    
    function windowstring (w_open, w_kipp, w_close){
       var output;
       if (w_open==0 && w_kipp==0) {
           output ="Zu";
       } else {
           output = "O:"+ w_open +" K:"+ w_kipp;
       };
       return output;
    }
    //Das Erdgeschoß ist noch im Umbau, deswegen noch nicht im Skript enthalten
    
    

    Das ganze sieht dann so aus:

    IMG_20200524_161732.jpg
    IMG_20200524_161726.jpg

    Aktuell habe ich nur noch das Problem, dass ich kein OTA Update auf dem ESP32 machen kann, da das abbricht. Per USB lässt er sich aber problemlos flashen.

    In Summe hat die Hardware ca. 70 EUR gekostet (30 EUR für das ESP Board und 37 EUR für das Display mit Versand)

    Viel Spass beim nachmachen, es war einfacher als befürchtet:-)

    Alexander

    L FredFF 2 Antworten Letzte Antwort
    3
    • L lxs

      Hallo,

      Ich würde euch gerne mein kleines Projekt vorstellen. Ich habe mir ein Display gebaut, welches ich an der Haustüre innen verbauen will, so dass ich auf einen Blick sehe ob z.B. noch Fenster offen sind. Ausserdem habe ich gleich noch eine Anwesenheitserkennung mit aufgebaut.

      Eingesetzt habe ich:

      • Olimex ESP32-POE-ISO Board: Bluetooth Low Energy Scanner und Ansteuerung für das Display
      • Waveshare 400x300, 4.2inch E-Ink raw display (Artikelnr. 13186)
      • Waveshare 4.2inch e-Paper Raw Panel Case (Artikelnr. 16116
      • Waveshare Universal e-Paper Raw Panel Driver HAT (Artikelnr 13512)
      • Gigaset G-Tag Bluetooth Low Energy beacons

      Das Setup ist folgendes:

      Das ESP32 Board habe ich mit ESPHome programmiert. Die Verbindung zum iobroker geht über mqtt. Das ESP32 Board wird über POE mit Strom und LAN versorgt. Am Ende wird das in eine Unterputz-Installationsdose versenkt und das Display auf einer Blindabdeckung auf dem Schalterrahmen befestigt.

      Hier der relevante Code:

      Die yaml-Datei für ESPhome:

      esphome:
        name: bt_eingang
        platform: ESP32
        board: esp32-poe-iso
      
      ethernet:
        type: LAN8720
        mdc_pin: GPIO23
        mdio_pin: GPIO18
        clk_mode: GPIO17_OUT
        phy_addr: 0
        power_pin: GPIO12
        
      font:
        - file: "ubuntu.ttf"
          id: my_font
          size: 20
      spi:
        clk_pin: 14
        mosi_pin: 4
        
      
      esp32_ble_tracker:
      
      binary_sensor:
        - platform: ble_presence
          mac_address: 58:9E:XX:XX:XX:XX
          name: "Tracker white"
          id: track_w
        - platform: ble_presence
          mac_address: 58:9E:XX:XX:XX:XX
          name: "Tracker black"
          id: track_b
      
      text_sensor:
        - platform: mqtt_subscribe
          name: "Aussentemperatur"
          id: temp_out
          topic: bt_eingang/display/temp_out
        - platform: mqtt_subscribe
          name: "Headline"
          id: fc_symbol
          topic: bt_eingang/display/headline
        - platform: mqtt_subscribe
          name: "Line 2OG Licht"
          id: line_2OG_licht
          topic: bt_eingang/display/line_2OG_licht
        - platform: mqtt_subscribe
          name: "Line 2OG Fenster"
          id: line_2OG_fenster
          topic: bt_eingang/display/line_2OG_fenster
        - platform: mqtt_subscribe
          name: "Line 1OG Licht"
          id: line_1OG_licht
          topic: bt_eingang/display/line_1OG_licht
        - platform: mqtt_subscribe
          name: "Line 1OG Fenster"
          id: line_1OG_fenster
          topic: bt_eingang/display/line_1OG_fenster
        - platform: mqtt_subscribe
          name: "Line EG Fenster"
          id: line_EG_fenster
          topic: bt_eingang/display/line_EG_fenster
        - platform: mqtt_subscribe
          name: "Line EG Licht"
          id: line_EG_licht
          topic: bt_eingang/display/line_EG_licht    
        - platform: mqtt_subscribe
          name: "Anwesenheit"
          id: presence_string
          topic: bt_eingang/display/presence_string
      
      #Bilder aus dem DasWetter-Adapter invertiert und als jpg ohne Transparenz gespeichert
      
      image:
        - file: "icons/tiempo-weather/galeria5/PNG/mine/1.jpg"
          id: image_1
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/2.jpg"
          id: image_2
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/3.jpg"
          id: image_3
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/4.jpg"
          id: image_4
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/5.jpg"
          id: image_5
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/6.jpg"
          id: image_6
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/7.jpg"
          id: image_7
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/8.jpg"
          id: image_8
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/9.jpg"
          id: image_9
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/10.jpg"
          id: image_10
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/11.jpg"
          id: image_11
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/12.jpg"
          id: image_12
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/13.jpg"
          id: image_13
          resize: 60x60
        - file: "icons/tiempo-weather/galeria5/PNG/mine/14.jpg"
          id: image_14
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/15.jpg"
          id: image_15
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/16.jpg"
          id: image_16
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/17.jpg"
          id: image_17
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/18.jpg"
          id: image_18
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/19.jpg"
          id: image_19
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/20.jpg"
          id: image_20
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/21.jpg"
          id: image_21
          resize: 40x40
        - file: "icons/tiempo-weather/galeria5/PNG/mine/22.jpg"
          id: image_22
          resize: 40x40
       
      
      display:
        - platform: waveshare_epaper
          cs_pin: 16
          dc_pin: 15
          busy_pin: 13
          reset_pin: 2
          model: 4.20in
          update_interval: 3600s  #Displayrefresh flickert bei dem Display leider
          id: my_display
          lambda: |-
            it.printf(10,20, id(my_font), "Temperatur: %s", id(temp_out).state.c_str());
            it.print(250,10, id(my_font), "Vorhersage:");
            if (id(fc_symbol).state == "1") { it.image(360, 0, id(image_1)); };
            if (id(fc_symbol).state == "2") { it.image(360, 0, id(image_2)); };
            if (id(fc_symbol).state == "3") { it.image(360, 0, id(image_3)); };
            if (id(fc_symbol).state == "4") { it.image(360, 0, id(image_4)); };
            if (id(fc_symbol).state == "5") { it.image(360, 0, id(image_5)); };
            if (id(fc_symbol).state == "6") { it.image(360, 0, id(image_6)); };
            if (id(fc_symbol).state == "7") { it.image(360, 0, id(image_7)); };
            if (id(fc_symbol).state == "8") { it.image(360, 0, id(image_8)); };
            if (id(fc_symbol).state == "9") { it.image(360, 0, id(image_9)); };
            if (id(fc_symbol).state == "10") { it.image(360, 0, id(image_10)); };
            if (id(fc_symbol).state == "11") { it.image(360, 0, id(image_11)); };
            if (id(fc_symbol).state == "12") { it.image(360, 0, id(image_12)); };
            if (id(fc_symbol).state == "13") { it.image(360, 0, id(image_13)); };
            if (id(fc_symbol).state == "14") { it.image(360, 0, id(image_14)); };
            if (id(fc_symbol).state == "15") { it.image(360, 0, id(image_15)); };
            if (id(fc_symbol).state == "16") { it.image(360, 0, id(image_16)); };
            if (id(fc_symbol).state == "17") { it.image(360, 0, id(image_17)); };
            if (id(fc_symbol).state == "18") { it.image(360, 0, id(image_18)); };
            if (id(fc_symbol).state == "19") { it.image(360, 0, id(image_19)); };
            if (id(fc_symbol).state == "20") { it.image(360, 0, id(image_20)); };
            if (id(fc_symbol).state == "21") { it.image(360, 0, id(image_21)); };
            if (id(fc_symbol).state == "22") { it.image(360, 0, id(image_22)); };
           //geht sicher auch schöner in einer Zeile Code...
            it.line(0, 47, 400, 47);
            //Table
            it.line(100, 110, 300, 110); 
            it.line(100, 150, 300, 150);
            it.line(100, 190, 300, 190); 
            it.line(100, 230, 300, 230);
            it.line(200, 110, 200, 230);
            it.line(100, 110, 100, 230);
            it.line(300, 110, 300, 230);
            //Lastline
            it.line(0, 255, 400, 255);
            it.print(130,80,id(my_font), "Licht");
            it.print(220,80,id(my_font), "Fenster");
            it.print(50,120,id(my_font), "2 OG");
            it.print(50,160,id(my_font), "1 OG");
            it.print(70,200,id(my_font), "EG");
            it.printf(110,130, id(my_font), "%s", id(line_2OG_licht).state.c_str());
            it.printf(210,130, id(my_font), "%s", id(line_2OG_fenster).state.c_str());
            it.printf(110,170, id(my_font), "%s", id(line_1OG_licht).state.c_str());
            it.printf(210,170, id(my_font), "%s", id(line_1OG_fenster).state.c_str());
            it.printf(110,210, id(my_font), "%s", id(line_EG_licht).state.c_str());
            it.printf(210,210, id(my_font), "%s", id(line_EG_fenster).state.c_str());
            it.printf(10,275,id(my_font), "Anwesenheit: %s", id(presence_string).state.c_str());
      
      
      # Enable logging
      logger:
      mqtt:
        broker: #IP vom iobroker
        username: #wie in iobroker mqtt adapter
        password: #wie in iobroker mqtt adapter
        client_id: bt_Eingang
      #  log_topic: bt_eingang/log/
        on_message: # Manueller refresh des Displays bei Änderung
          topic: bt_eingang/display/refresh
          payload: "ON"
          then:
            - component.update: my_display
            
      ota:
      

      Das spannende (aber dann doch triviale - man kann hier recht frei entscheiden) war hier die HW Verkabelung. Diese ist im yaml dokumentiert. die GPIO Pins stehen im Plan auf der Olimex-Seite.

      Auf dem iobroker habe ich ein Javascript um per mqtt die entsprechenden Werte zu liefern:

      var fenster1OG=['hm-rpc.3.0000XXXXXXXXXX.1.STATE'/*Fensterkontakt Schlafzimmer:1 STATE*/, 
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Balko Arbeitszimmer:1 STATE*/,
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster KiZi:1 STATE*/,
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Bad 1OG STATE*/,
      'hm-rpc.0.MEQ02XXXXX.1.STATE'/*Fenster Fenster AZ STATE*/];
      
      var fenster2OG=['hm-rpc.0.JEQ0XXXXXX.1.STATE'/*Fenster Dach Nord:1 STATE*/,
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Küche STATE*/,
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Gaube STATE*/,
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Fenster West:1 STATE*/,
      'hm-rpc.0.KEQ01XXXXX.1.STATE'/*Fenster Badewanne:1 STATE*/,
      'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Bad 2OG:1 STATE*/];
      
      var presence=['javascript.1.presence_black'/*presence black*/,'javascript.1.presence_white'/*javascript 1 presence white*/]; //u.a. aus den Werten des BLE Scanners ermittler, aber noch aus einem zweiten Scanner und mit einer Hysterese
      
      on({id:'hm-rega.0.XXX'/*Licht 1OG*/, change: "ne"}, function(obj) { //Variable fürs Licht wird bei mir in der CCU gepflegt.
         var output;
         var input=obj.state.val;
         if (input) {
             output="An";
         } else {
             output="Aus";
         };
         setState('mqtt.0.bt_eingang.display.line_1OG_licht'/*bt eingang/display/line 1OG licht*/,output);
         redraw_display();
      });
      
      on({id:'hm-rega.0.1XXX'/*Licht2OG*/, change: "ne"}, function(obj) {
         var output;
         var input=obj.state.val;
         if (input) {
             output="An";
         } else {
             output="Aus";
         };
         setState('mqtt.0.bt_eingang.display.line_2OG_licht'/*bt eingang/display/line 1OG licht*/,output);
         redraw_display();
      });
      
      on({id:presence, change: "ne"}, function(obj) {
         var output="";
         if (getState("javascript.1.presence_black").val){
             output = output +"Schwarz "; //Hier kann man die Namen der Besitzer eintragen
         };
         if (getState("javascript.1.presence_white").val) {
             output = output + "Weiss ";
         };
         setState('mqtt.0.bt_eingang.display.presence_string'/*bt eingang/display/presence string*/,output);
         redraw_display();
      }); 
      
      on({id:fenster1OG, change: "ne"}, function(obj) {
         var output;
         var input=obj.state.val;
         var open_1OG=0;
         var gekippt_1OG=0;
         var closed_1OG=0;
         for (var i = 0; i < fenster1OG.length; i++) {
             var ws = getState(fenster1OG[i]).val;
             if (fenster1OG[i]=="hm-rpc.3.0000DXXXXXXX.1.STATE") {  //Fensterkontakt mit nur zwei Zuständen
                 if (ws==0) {
                     closed_1OG++;
                 } else if (ws==1) {
                     open_1OG++;
                 };
             } else {   //Normalerweise habe ich Griffsensoren mit 3 Zuständen
                 if (ws==0) {
                     closed_1OG++;
                 } else if (ws==1) {
                     gekippt_1OG++;
                 } else if (ws==2) {
                     open_1OG++;
                 }
             };
         };
         output = windowstring(open_1OG,gekippt_1OG,closed_1OG);
         setState('mqtt.0.bt_eingang.display.line_1OG_fenster'/*bt eingang/display/line 1OG fenster*/,output);
         redraw_display();
      });
      
      on({id:fenster2OG, change: "ne"}, function(obj) {
         var output;
         var input=obj.state.val;
         var open_2OG=0;
         var gekippt_2OG=0;
         var closed_2OG=0;
         for (var i = 0; i < fenster2OG.length; i++) {
             var ws = getState(fenster2OG[i]).val;
          
             if (fenster2OG[i]=="hm-rpc.3.000XXXXXX1.STATE") { 
                 if (ws==0) {
                     closed_2OG++;
                 } else if (ws==1) {
                     open_2OG++;
                 };
             } else {
                 if (ws==0) {
                     closed_2OG++;
                 } else if (ws==1) {
                     gekippt_2OG++;
                 } else if (ws==2) {
                     open_2OG++;
                 }
             };
         };
         output = windowstring(open_2OG,gekippt_2OG,closed_2OG);
         setState('mqtt.0.bt_eingang.display.line_2OG_fenster'/*bt eingang/display/line 1OG fenster*/,output);
         redraw_display();
      });
      
      on({id:'netatmo.0.XXXX.XXX.Temperature.Temperature'/*Temperature*/, change: "ne"}, function(obj) {
         setState('mqtt.0.bt_eingang.display.temp_out'/*bt eingang/display/temp out*/,obj.state.val);
      }); //Aussentemperatur. Änderung macht kein Display-Refresh, da das e-ink ca. 2-3 Sekunden beim aktualisieren flackert. Wird bei der nächsten Änderung oder nach 3600s wie im esphome-Skript aktualisiert. 
      
      on({id:"daswetter.0.NextHours.Location_1.Day_1.in1hours.symbol_value", change:"ne"}, function(obj){
         setState('mqtt.0.bt_eingang.display.headline'/*bt eingang/display/headline*/,obj.state.val);
         redraw_display();
      }); //Forecast für die nächste Stunde. 
      
      
      function redraw_display() {
         setState('mqtt.0.bt_eingang.display.refresh'/*bt eingang/display/refresh*/,"ON");
         setStateDelayed('mqtt.0.bt_eingang.display.refresh', "OFF",  1000);    
      }; //mit "ON" wird das Display aktualisiert. 
      
      
      function windowstring (w_open, w_kipp, w_close){
         var output;
         if (w_open==0 && w_kipp==0) {
             output ="Zu";
         } else {
             output = "O:"+ w_open +" K:"+ w_kipp;
         };
         return output;
      }
      //Das Erdgeschoß ist noch im Umbau, deswegen noch nicht im Skript enthalten
      
      

      Das ganze sieht dann so aus:

      IMG_20200524_161732.jpg
      IMG_20200524_161726.jpg

      Aktuell habe ich nur noch das Problem, dass ich kein OTA Update auf dem ESP32 machen kann, da das abbricht. Per USB lässt er sich aber problemlos flashen.

      In Summe hat die Hardware ca. 70 EUR gekostet (30 EUR für das ESP Board und 37 EUR für das Display mit Versand)

      Viel Spass beim nachmachen, es war einfacher als befürchtet:-)

      Alexander

      L Offline
      L Offline
      lxs
      schrieb am zuletzt editiert von
      #2

      Hi,

      Da ich gerade eine Frage zu dem Projekt bekommen habe, hier ein kleines Update wie das ganze im eingebauten Zustand aussieht :

      IMG_20210125_142326.jpg IMG_20210125_142335.jpg

      Unter der Blindabdeckung ist eine EDV Dose in der das ESP32 Modul mit PoE angeschlossen ist. Die obere Dose ist bis auf das kleine Board für die Displaysteuerung leer und hat auch eine Blindabdeckung an der mit einem Klebeband das Display befestigt ist. In der mittleren Dose ist ein haus-bus.de Multitaster (tolle Schalter!) .

      Die EDV Dose war recht knapp, da das Cat6 Kabel mit Ethernet-Stecker etwas unflexibel ist, aber es hat gepasst.

      MikewolfM 1 Antwort Letzte Antwort
      2
      • L lxs

        Hallo,

        Ich würde euch gerne mein kleines Projekt vorstellen. Ich habe mir ein Display gebaut, welches ich an der Haustüre innen verbauen will, so dass ich auf einen Blick sehe ob z.B. noch Fenster offen sind. Ausserdem habe ich gleich noch eine Anwesenheitserkennung mit aufgebaut.

        Eingesetzt habe ich:

        • Olimex ESP32-POE-ISO Board: Bluetooth Low Energy Scanner und Ansteuerung für das Display
        • Waveshare 400x300, 4.2inch E-Ink raw display (Artikelnr. 13186)
        • Waveshare 4.2inch e-Paper Raw Panel Case (Artikelnr. 16116
        • Waveshare Universal e-Paper Raw Panel Driver HAT (Artikelnr 13512)
        • Gigaset G-Tag Bluetooth Low Energy beacons

        Das Setup ist folgendes:

        Das ESP32 Board habe ich mit ESPHome programmiert. Die Verbindung zum iobroker geht über mqtt. Das ESP32 Board wird über POE mit Strom und LAN versorgt. Am Ende wird das in eine Unterputz-Installationsdose versenkt und das Display auf einer Blindabdeckung auf dem Schalterrahmen befestigt.

        Hier der relevante Code:

        Die yaml-Datei für ESPhome:

        esphome:
          name: bt_eingang
          platform: ESP32
          board: esp32-poe-iso
        
        ethernet:
          type: LAN8720
          mdc_pin: GPIO23
          mdio_pin: GPIO18
          clk_mode: GPIO17_OUT
          phy_addr: 0
          power_pin: GPIO12
          
        font:
          - file: "ubuntu.ttf"
            id: my_font
            size: 20
        spi:
          clk_pin: 14
          mosi_pin: 4
          
        
        esp32_ble_tracker:
        
        binary_sensor:
          - platform: ble_presence
            mac_address: 58:9E:XX:XX:XX:XX
            name: "Tracker white"
            id: track_w
          - platform: ble_presence
            mac_address: 58:9E:XX:XX:XX:XX
            name: "Tracker black"
            id: track_b
        
        text_sensor:
          - platform: mqtt_subscribe
            name: "Aussentemperatur"
            id: temp_out
            topic: bt_eingang/display/temp_out
          - platform: mqtt_subscribe
            name: "Headline"
            id: fc_symbol
            topic: bt_eingang/display/headline
          - platform: mqtt_subscribe
            name: "Line 2OG Licht"
            id: line_2OG_licht
            topic: bt_eingang/display/line_2OG_licht
          - platform: mqtt_subscribe
            name: "Line 2OG Fenster"
            id: line_2OG_fenster
            topic: bt_eingang/display/line_2OG_fenster
          - platform: mqtt_subscribe
            name: "Line 1OG Licht"
            id: line_1OG_licht
            topic: bt_eingang/display/line_1OG_licht
          - platform: mqtt_subscribe
            name: "Line 1OG Fenster"
            id: line_1OG_fenster
            topic: bt_eingang/display/line_1OG_fenster
          - platform: mqtt_subscribe
            name: "Line EG Fenster"
            id: line_EG_fenster
            topic: bt_eingang/display/line_EG_fenster
          - platform: mqtt_subscribe
            name: "Line EG Licht"
            id: line_EG_licht
            topic: bt_eingang/display/line_EG_licht    
          - platform: mqtt_subscribe
            name: "Anwesenheit"
            id: presence_string
            topic: bt_eingang/display/presence_string
        
        #Bilder aus dem DasWetter-Adapter invertiert und als jpg ohne Transparenz gespeichert
        
        image:
          - file: "icons/tiempo-weather/galeria5/PNG/mine/1.jpg"
            id: image_1
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/2.jpg"
            id: image_2
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/3.jpg"
            id: image_3
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/4.jpg"
            id: image_4
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/5.jpg"
            id: image_5
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/6.jpg"
            id: image_6
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/7.jpg"
            id: image_7
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/8.jpg"
            id: image_8
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/9.jpg"
            id: image_9
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/10.jpg"
            id: image_10
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/11.jpg"
            id: image_11
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/12.jpg"
            id: image_12
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/13.jpg"
            id: image_13
            resize: 60x60
          - file: "icons/tiempo-weather/galeria5/PNG/mine/14.jpg"
            id: image_14
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/15.jpg"
            id: image_15
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/16.jpg"
            id: image_16
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/17.jpg"
            id: image_17
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/18.jpg"
            id: image_18
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/19.jpg"
            id: image_19
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/20.jpg"
            id: image_20
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/21.jpg"
            id: image_21
            resize: 40x40
          - file: "icons/tiempo-weather/galeria5/PNG/mine/22.jpg"
            id: image_22
            resize: 40x40
         
        
        display:
          - platform: waveshare_epaper
            cs_pin: 16
            dc_pin: 15
            busy_pin: 13
            reset_pin: 2
            model: 4.20in
            update_interval: 3600s  #Displayrefresh flickert bei dem Display leider
            id: my_display
            lambda: |-
              it.printf(10,20, id(my_font), "Temperatur: %s", id(temp_out).state.c_str());
              it.print(250,10, id(my_font), "Vorhersage:");
              if (id(fc_symbol).state == "1") { it.image(360, 0, id(image_1)); };
              if (id(fc_symbol).state == "2") { it.image(360, 0, id(image_2)); };
              if (id(fc_symbol).state == "3") { it.image(360, 0, id(image_3)); };
              if (id(fc_symbol).state == "4") { it.image(360, 0, id(image_4)); };
              if (id(fc_symbol).state == "5") { it.image(360, 0, id(image_5)); };
              if (id(fc_symbol).state == "6") { it.image(360, 0, id(image_6)); };
              if (id(fc_symbol).state == "7") { it.image(360, 0, id(image_7)); };
              if (id(fc_symbol).state == "8") { it.image(360, 0, id(image_8)); };
              if (id(fc_symbol).state == "9") { it.image(360, 0, id(image_9)); };
              if (id(fc_symbol).state == "10") { it.image(360, 0, id(image_10)); };
              if (id(fc_symbol).state == "11") { it.image(360, 0, id(image_11)); };
              if (id(fc_symbol).state == "12") { it.image(360, 0, id(image_12)); };
              if (id(fc_symbol).state == "13") { it.image(360, 0, id(image_13)); };
              if (id(fc_symbol).state == "14") { it.image(360, 0, id(image_14)); };
              if (id(fc_symbol).state == "15") { it.image(360, 0, id(image_15)); };
              if (id(fc_symbol).state == "16") { it.image(360, 0, id(image_16)); };
              if (id(fc_symbol).state == "17") { it.image(360, 0, id(image_17)); };
              if (id(fc_symbol).state == "18") { it.image(360, 0, id(image_18)); };
              if (id(fc_symbol).state == "19") { it.image(360, 0, id(image_19)); };
              if (id(fc_symbol).state == "20") { it.image(360, 0, id(image_20)); };
              if (id(fc_symbol).state == "21") { it.image(360, 0, id(image_21)); };
              if (id(fc_symbol).state == "22") { it.image(360, 0, id(image_22)); };
             //geht sicher auch schöner in einer Zeile Code...
              it.line(0, 47, 400, 47);
              //Table
              it.line(100, 110, 300, 110); 
              it.line(100, 150, 300, 150);
              it.line(100, 190, 300, 190); 
              it.line(100, 230, 300, 230);
              it.line(200, 110, 200, 230);
              it.line(100, 110, 100, 230);
              it.line(300, 110, 300, 230);
              //Lastline
              it.line(0, 255, 400, 255);
              it.print(130,80,id(my_font), "Licht");
              it.print(220,80,id(my_font), "Fenster");
              it.print(50,120,id(my_font), "2 OG");
              it.print(50,160,id(my_font), "1 OG");
              it.print(70,200,id(my_font), "EG");
              it.printf(110,130, id(my_font), "%s", id(line_2OG_licht).state.c_str());
              it.printf(210,130, id(my_font), "%s", id(line_2OG_fenster).state.c_str());
              it.printf(110,170, id(my_font), "%s", id(line_1OG_licht).state.c_str());
              it.printf(210,170, id(my_font), "%s", id(line_1OG_fenster).state.c_str());
              it.printf(110,210, id(my_font), "%s", id(line_EG_licht).state.c_str());
              it.printf(210,210, id(my_font), "%s", id(line_EG_fenster).state.c_str());
              it.printf(10,275,id(my_font), "Anwesenheit: %s", id(presence_string).state.c_str());
        
        
        # Enable logging
        logger:
        mqtt:
          broker: #IP vom iobroker
          username: #wie in iobroker mqtt adapter
          password: #wie in iobroker mqtt adapter
          client_id: bt_Eingang
        #  log_topic: bt_eingang/log/
          on_message: # Manueller refresh des Displays bei Änderung
            topic: bt_eingang/display/refresh
            payload: "ON"
            then:
              - component.update: my_display
              
        ota:
        

        Das spannende (aber dann doch triviale - man kann hier recht frei entscheiden) war hier die HW Verkabelung. Diese ist im yaml dokumentiert. die GPIO Pins stehen im Plan auf der Olimex-Seite.

        Auf dem iobroker habe ich ein Javascript um per mqtt die entsprechenden Werte zu liefern:

        var fenster1OG=['hm-rpc.3.0000XXXXXXXXXX.1.STATE'/*Fensterkontakt Schlafzimmer:1 STATE*/, 
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Balko Arbeitszimmer:1 STATE*/,
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster KiZi:1 STATE*/,
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Bad 1OG STATE*/,
        'hm-rpc.0.MEQ02XXXXX.1.STATE'/*Fenster Fenster AZ STATE*/];
        
        var fenster2OG=['hm-rpc.0.JEQ0XXXXXX.1.STATE'/*Fenster Dach Nord:1 STATE*/,
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Küche STATE*/,
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Gaube STATE*/,
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Fenster West:1 STATE*/,
        'hm-rpc.0.KEQ01XXXXX.1.STATE'/*Fenster Badewanne:1 STATE*/,
        'hm-rpc.0.KEQ00XXXXX.1.STATE'/*Fenster Bad 2OG:1 STATE*/];
        
        var presence=['javascript.1.presence_black'/*presence black*/,'javascript.1.presence_white'/*javascript 1 presence white*/]; //u.a. aus den Werten des BLE Scanners ermittler, aber noch aus einem zweiten Scanner und mit einer Hysterese
        
        on({id:'hm-rega.0.XXX'/*Licht 1OG*/, change: "ne"}, function(obj) { //Variable fürs Licht wird bei mir in der CCU gepflegt.
           var output;
           var input=obj.state.val;
           if (input) {
               output="An";
           } else {
               output="Aus";
           };
           setState('mqtt.0.bt_eingang.display.line_1OG_licht'/*bt eingang/display/line 1OG licht*/,output);
           redraw_display();
        });
        
        on({id:'hm-rega.0.1XXX'/*Licht2OG*/, change: "ne"}, function(obj) {
           var output;
           var input=obj.state.val;
           if (input) {
               output="An";
           } else {
               output="Aus";
           };
           setState('mqtt.0.bt_eingang.display.line_2OG_licht'/*bt eingang/display/line 1OG licht*/,output);
           redraw_display();
        });
        
        on({id:presence, change: "ne"}, function(obj) {
           var output="";
           if (getState("javascript.1.presence_black").val){
               output = output +"Schwarz "; //Hier kann man die Namen der Besitzer eintragen
           };
           if (getState("javascript.1.presence_white").val) {
               output = output + "Weiss ";
           };
           setState('mqtt.0.bt_eingang.display.presence_string'/*bt eingang/display/presence string*/,output);
           redraw_display();
        }); 
        
        on({id:fenster1OG, change: "ne"}, function(obj) {
           var output;
           var input=obj.state.val;
           var open_1OG=0;
           var gekippt_1OG=0;
           var closed_1OG=0;
           for (var i = 0; i < fenster1OG.length; i++) {
               var ws = getState(fenster1OG[i]).val;
               if (fenster1OG[i]=="hm-rpc.3.0000DXXXXXXX.1.STATE") {  //Fensterkontakt mit nur zwei Zuständen
                   if (ws==0) {
                       closed_1OG++;
                   } else if (ws==1) {
                       open_1OG++;
                   };
               } else {   //Normalerweise habe ich Griffsensoren mit 3 Zuständen
                   if (ws==0) {
                       closed_1OG++;
                   } else if (ws==1) {
                       gekippt_1OG++;
                   } else if (ws==2) {
                       open_1OG++;
                   }
               };
           };
           output = windowstring(open_1OG,gekippt_1OG,closed_1OG);
           setState('mqtt.0.bt_eingang.display.line_1OG_fenster'/*bt eingang/display/line 1OG fenster*/,output);
           redraw_display();
        });
        
        on({id:fenster2OG, change: "ne"}, function(obj) {
           var output;
           var input=obj.state.val;
           var open_2OG=0;
           var gekippt_2OG=0;
           var closed_2OG=0;
           for (var i = 0; i < fenster2OG.length; i++) {
               var ws = getState(fenster2OG[i]).val;
            
               if (fenster2OG[i]=="hm-rpc.3.000XXXXXX1.STATE") { 
                   if (ws==0) {
                       closed_2OG++;
                   } else if (ws==1) {
                       open_2OG++;
                   };
               } else {
                   if (ws==0) {
                       closed_2OG++;
                   } else if (ws==1) {
                       gekippt_2OG++;
                   } else if (ws==2) {
                       open_2OG++;
                   }
               };
           };
           output = windowstring(open_2OG,gekippt_2OG,closed_2OG);
           setState('mqtt.0.bt_eingang.display.line_2OG_fenster'/*bt eingang/display/line 1OG fenster*/,output);
           redraw_display();
        });
        
        on({id:'netatmo.0.XXXX.XXX.Temperature.Temperature'/*Temperature*/, change: "ne"}, function(obj) {
           setState('mqtt.0.bt_eingang.display.temp_out'/*bt eingang/display/temp out*/,obj.state.val);
        }); //Aussentemperatur. Änderung macht kein Display-Refresh, da das e-ink ca. 2-3 Sekunden beim aktualisieren flackert. Wird bei der nächsten Änderung oder nach 3600s wie im esphome-Skript aktualisiert. 
        
        on({id:"daswetter.0.NextHours.Location_1.Day_1.in1hours.symbol_value", change:"ne"}, function(obj){
           setState('mqtt.0.bt_eingang.display.headline'/*bt eingang/display/headline*/,obj.state.val);
           redraw_display();
        }); //Forecast für die nächste Stunde. 
        
        
        function redraw_display() {
           setState('mqtt.0.bt_eingang.display.refresh'/*bt eingang/display/refresh*/,"ON");
           setStateDelayed('mqtt.0.bt_eingang.display.refresh', "OFF",  1000);    
        }; //mit "ON" wird das Display aktualisiert. 
        
        
        function windowstring (w_open, w_kipp, w_close){
           var output;
           if (w_open==0 && w_kipp==0) {
               output ="Zu";
           } else {
               output = "O:"+ w_open +" K:"+ w_kipp;
           };
           return output;
        }
        //Das Erdgeschoß ist noch im Umbau, deswegen noch nicht im Skript enthalten
        
        

        Das ganze sieht dann so aus:

        IMG_20200524_161732.jpg
        IMG_20200524_161726.jpg

        Aktuell habe ich nur noch das Problem, dass ich kein OTA Update auf dem ESP32 machen kann, da das abbricht. Per USB lässt er sich aber problemlos flashen.

        In Summe hat die Hardware ca. 70 EUR gekostet (30 EUR für das ESP Board und 37 EUR für das Display mit Versand)

        Viel Spass beim nachmachen, es war einfacher als befürchtet:-)

        Alexander

        FredFF Online
        FredFF Online
        FredF
        Most Active Forum Testing
        schrieb am zuletzt editiert von
        #3

        @lxs sagte in Vorstellung: e-Ink display für Hausstatus:

        Die Verbindung zum iobroker geht über mqtt.

        Vielleicht magst du mal testen:
        Es gibt mittlerweile einen ESPhome Adapter zwar noch alpha...
        Nutzt die API, also kein MQTT nötig. Habe ihn installiert und er läuft.
        https://github.com/iobroker-community-adapters/ioBroker.esphome

        1 Antwort Letzte Antwort
        0
        • L lxs

          Hi,

          Da ich gerade eine Frage zu dem Projekt bekommen habe, hier ein kleines Update wie das ganze im eingebauten Zustand aussieht :

          IMG_20210125_142326.jpg IMG_20210125_142335.jpg

          Unter der Blindabdeckung ist eine EDV Dose in der das ESP32 Modul mit PoE angeschlossen ist. Die obere Dose ist bis auf das kleine Board für die Displaysteuerung leer und hat auch eine Blindabdeckung an der mit einem Klebeband das Display befestigt ist. In der mittleren Dose ist ein haus-bus.de Multitaster (tolle Schalter!) .

          Die EDV Dose war recht knapp, da das Cat6 Kabel mit Ethernet-Stecker etwas unflexibel ist, aber es hat gepasst.

          MikewolfM Offline
          MikewolfM Offline
          Mikewolf
          schrieb am zuletzt editiert von Mikewolf
          #4

          @lxs
          hallo , gibts ne step by step anleitung ???
          schaffe es leider nicht auch nicht mit hilfe von google....
          kommt immer error mapping bei spi definition

          apping values are not allowed here
            in "/config/esphome/esphome-web-8c4680.yaml", line 146, column 11:
                  cs_pin: 16
          

          Mit freundlichen Grüßen
          mikewolf

          Homematic (ca450 Rf komponenten), FS20,Alexas,Sonoff,ESP,Arduino,Lightly,Milight,NEEO,Harmony,Synology,HP-Gen8

          RF-link,Dreamboxen,Raspi,Cubie,Odroid,Fritz,Xiaomi-Vaccum,

          B 1 Antwort Letzte Antwort
          0
          • MikewolfM Mikewolf

            @lxs
            hallo , gibts ne step by step anleitung ???
            schaffe es leider nicht auch nicht mit hilfe von google....
            kommt immer error mapping bei spi definition

            apping values are not allowed here
              in "/config/esphome/esphome-web-8c4680.yaml", line 146, column 11:
                    cs_pin: 16
            

            Mit freundlichen Grüßen
            mikewolf

            B Offline
            B Offline
            bernd33-1
            schrieb am zuletzt editiert von
            #5

            @mikewolf Hi, ich hab einen ESP8266 verwendet. Dabei hab ich festgestellt, dass die EPaper Displays etwas sensibel mit den verwendeten Pins sind. Ich hab es so verbunden:

            Display -> ESP8266

            Busy -> D2
            Reset -> D1
            DC -> D4
            CS -> D8
            CLK -> D5
            Din -> D7
            GND -> GND (Masse)
            Vcc -> 3.3V am ESP8266

            VORSICHT1: In der YAML-Datei wird statt z.B. "D4" die GPIO-Nummer angegeben. D4 ist z.B. GPIO2

            VORSICHT2: Man muss die Font-Datei, die in der YAML angegeben ist auf den IOBroker hoch laden. Bei mir ist es die arial.ttf und hat die ID: font1. Wohin hochladen? Hier hin: /opt/iobroker/iobroker-data/esphome.0

            Hier meine YAML:

            esphome:
              name: 42display
              platform: ESP8266
              board: esp01_1m
            
            # Enable logging
            logger:
            
            # Enable Home Assistant API
            api:
            
            ota:
              password: "ist-geheim"
            
            wifi:
              ssid: "Ich-hoere-euch-beim-Sex"
              password: "auch-geheim"
            
              # Enable fallback hotspot (captive portal) in case wifi connection fails
              ap:
                ssid: "42Display Fallback Hotspot"
                password: "jajaja"
            
            captive_portal:
            
            spi:
              clk_pin: GPIO14
              mosi_pin: GPIO13
              
            font:
              - file: "arial.ttf"
                id: font1
                size: 12
                
            mqtt:
              broker: Die-IP-deine-MQTT/IOBroker
              #username: #wie in iobroker mqtt adapter
              #password: #wie in iobroker mqtt adapter
              client_id: 42Display
            #  log_topic: bt_eingang/log/
              on_message: # Manueller refresh des Displays bei Änderung
                topic: 42Display/display/refresh
                payload: "ON"
                then:
                  - component.update: my_display
                  
            text_sensor:
              - platform: mqtt_subscribe
                name: "Bio-Muell"
                id: bio_muell
                topic: 42Display/display/bio
              - platform: mqtt_subscribe
                name: "papier"
                id: papier
                topic: 42Display/display/papier
              
            display:
              - platform: waveshare_epaper
                cs_pin: GPIO15
                dc_pin: GPIO2
                busy_pin: GPIO4
                reset_pin: GPIO5
                model: 4.20in
                update_interval: 300s  #Displayrefresh flickert bei dem Display leider
                id: my_display
                lambda: |-
                  it.print(0, 0, id(font1), "Hello World!");  
                  it.printf(10,20, id(font1), "Bio-Muell: %s", id(bio_muell).state.c_str());
                  it.printf(10,35, id(font1), "Papier: %s", id(papier).state.c_str());
            
            
            
            1 Antwort Letzte Antwort
            0
            Antworten
            • In einem neuen Thema antworten
            Anmelden zum Antworten
            • Älteste zuerst
            • Neuste zuerst
            • Meiste Stimmen


            Support us

            ioBroker
            Community Adapters
            Donate

            970

            Online

            32.4k

            Benutzer

            81.5k

            Themen

            1.3m

            Beiträge
            Community
            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
            ioBroker Community 2014-2025
            logo
            • Anmelden

            • Du hast noch kein Konto? Registrieren

            • Anmelden oder registrieren, um zu suchen
            • Erster Beitrag
              Letzter Beitrag
            0
            • Home
            • Aktuell
            • Tags
            • Ungelesen 0
            • Kategorien
            • Unreplied
            • Beliebt
            • GitHub
            • Docu
            • Hilfe