RFID SENSOR in HomeAssistant


Anleitung

Um einen PN532 NFC/RFID Reader in Home Assistant einzubinden, überlegen wir uns erstmal die Funktion des Projekts.
Ein RFID Sensor liest einen Chip und führt dann die gewünschte Automatisierung aus.

Alle benötigten Bauteile findet Ihr übrigens hier:

Nun Zur Praxis:

  • Geht in Eurer Home Assistant instanz auf das Add-on ESPHome.
  • Klickt unten rechts auf das Grüne +
  • Wählt jetzt den Namen wie Ihr Eure D1 Mini nennen wollte. Im meinem Fall tagreader.
    ACHTUNG! Es dürfen nur Kleinbuchstaben verwendet werden.
  • Klickt auf “Next”
  • Wählt jetzt unter Device „Wemos D1 and Wemos D1 mini“ aus.
  • Klickt auf “Next”
  • Gebt bei „Wifi SSID“ den Namen Eures WLAN Netzwerkes ein. Und bei „Wifi Password“ entsprechend Euer WLAN Passwort.
  • Das Feld OTA Password könnt Ihr frei lassen.
  • Klickt auf „Submit“

Ihr solltet jetzt folgendes Feld sehen:

Nun Programmieren wir den D1 Mini!

  • Klickt auf „edit“
  • Kopiert den untenstehenden Code und fügt Ihn in ESPHome unterhalb von logger ein und ersetzt Euer API und OTA Passwort.
wifi:
  networks:
    - ssid: EUERWLAN          
      password: EUERPASSWORT
  ap:
    ssid: ${devicename}


captive_portal:

substitutions:
  devicename: tagreader
  friendly_name: TagReader

esphome:
  name: $devicename
  platform: ESP8266
  board: d1_mini

  on_boot:
    priority: -10
    then:
    - wait_until:
        api.connected:
    - logger.log: API is connected!
    - rtttl.play: "success:d=24,o=5,b=100:c,g,b"
    - light.turn_on:
        id: activity_led
        brightness: 100%
        red: 0%
        green: 0%
        blue: 100%
        flash_length: 500ms

switch:
- platform: template
  name: "${friendly_name} Buzzer EIN"
  id: buzzer_enabled
  icon: mdi:volume-high
  optimistic: true
  restore_state: true
- platform: template
  name: "${friendly_name} LED EIN"
  id: led_enabled
  icon: mdi:alarm-light-outline
  optimistic: true
  restore_state: true


logger:


api:
  password: "EUERAPIPASSWORT"
  services:
  - service: rfidreader_tag_ok
    then:
    - rtttl.play: "beep:d=16,o=5,b=100:b"

  - service: rfidreader_tag_ko
    then:
    - rtttl.play: "beep:d=8,o=5,b=100:b"

  - service: play_rtttl
    variables:
      song_str: string
    then:
    - rtttl.play: !lambda 'return song_str;'

  - service: write_tag_random
    then:
    - lambda: |-
        static const char alphanum[] = "0123456789abcdef";
        std::string uri = "//www.home-assistant.io/tag/";
        for (int i = 0; i < 8; i++)
          uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
        uri += "-";
        for (int j = 0; j < 3; j++) {
          for (int i = 0; i < 4; i++)
            uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
          uri += "-";
        }
        for (int i = 0; i < 12; i++)
          uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
        auto message = new nfc::NdefMessage();
        message->add_uri_record(uri);
        ESP_LOGD("tagreader", "Writing payload: %s", uri.c_str());
        id(pn532_board).write_mode(message);
  - service: write_tag_id
    variables:
      tag_id: string
    then:
    - lambda: |-
        auto message = new nfc::NdefMessage();
        std::string uri = "//www.home-assistant.io/tag/";
        uri += tag_id;
        message->add_uri_record(uri);
        id(pn532_board).write_mode(message);
  - service: clean_tag
    then:
    - lambda: 'id(pn532_board).clean_mode();'

  - service: cancel_writing
    then:
    - lambda: 'id(pn532_board).read_mode();'

ota:
  password: "EUEROVERTHEAIRPASSWORT"

i2c:
  scan: false
  frequency: 400kHz

pn532_i2c:
  id: pn532_board
  on_tag:
    then:
    - homeassistant.tag_scanned: !lambda |
        if (!tag.has_ndef_message()) {
          ESP_LOGD("tagreader", "No NDEF");
          return x;
        }
        auto message = tag.get_ndef_message();
        auto records = message->get_records();
        for (auto &record : records) {
          std::string payload = record->get_payload();
          size_t pos = payload.find("//www.home-assistant.io/tag/");
          if (pos != std::string::npos) {
            return payload.substr(pos + 34);
          }
        }
        ESP_LOGD("tagreader", "Bad NDEF, fallback to uid");
        return x;
    - if:
        condition:
          switch.is_on: buzzer_enabled
        then:
        - rtttl.play: "success:d=24,o=5,b=100:c,g,b"
    - if:
        condition:
          switch.is_on: led_enabled
        then:
        - light.turn_on:
            id: activity_led
            brightness: 100%
            red: 0%
            green: 100%
            blue: 0%
            flash_length: 500ms

output:
- platform: esp8266_pwm
  pin: D7
  id: buzzer

binary_sensor:
  - platform: status
    name: "${friendly_name} Status"

rtttl:
  output: buzzer

light:
- platform: fastled_clockless
  chipset: WS2812
  pin: D8
  default_transition_length: 10ms
  num_leds: 1
  rgb_order: GRB
  id: activity_led
  name: "${friendly_name} LED"
  restore_mode: ALWAYS_OFF

Das Ganze sollte nun so aussehen ergänzt mit Euren Daten:

  • Klickt nun auf “SAFE” und anschließend auf “CLOSE”.
  • Klickt jetzt auf die drei Punkte rechts neben “tagreader”und wählt “compile” aus.
  • Wenn die Kompilierung fertig ist, klickt auf. “Download Binary”

Nun geht es an Löten:

Schaltbild

Verkabelung

Kommen wir zur Verdrahtung der einzelnen Komponenten. Ich habe die Stromversorgung ausschließlich über den Ground Pin und den 5V Pin vom D1 Mini realisiert und diesen per USB an ein Netzteil angeschlossen. SDA kommt an PIN D2 und SCL an PIN D1. Der Vollständigkeit halber kommt VCC an den 5V PIN und GND an den G PIN.

Für den Buzzer und die LED habe ich mir eine Eigene Platine gelötet, um den D1 Mini nicht so mit Kabeln zuzumüllen.

Der Buzzer kommt mit + an den PIN D7 und mit dem anderen Pin an Ground.
Bei der WS2812 LED sieht es wie folgt aus: IN an PIN D8, GND an GND und 5V an 5V.

WICHTIG: An dem PN532 sind zwei kleine Dips. Dip Nr. 1 (Links) muss nach oben geschoben werden.

Das war schon der ganze Zauber:

Verbindet jetzt den D1 Mini per USB an Euren PC. Und öffnet das Programm ESP Home Flasher.

  • Wählt den COM Port aus mit dem Euer D1 Mini verbunden ist.
  • wählt die aus Home Assitant zuvor compilierte datei aus.
  • Klickt auf Flash ESP

 

Zurück in Home Assitant sollte Ihr jetzt folgende Geräte in eine Lovelacecard integrieren können:

  • TagReader Status
  • TagReader Buzzer EIN
  • TagReader LED
  • TagReader LED EIN

Um nun eine Automatisierung mit einem NFC Tag zu programmieren, geht in Home Assistant auf Einstellungen – NFC Tags.

Durch auflegen eines NFC Chips auf Euren Reader erscheint dieser nun in der Übersicht in Home Assistant.

Nun können wir eine Automatisierung bauen in dem wir auf den kleinen “Roboterkopf” klicken. In meinem Fall möchte ich ein Lampe an und wieder ausschalten.

UPDATE

Es scheint bei einigen Herstellern vom D1 Mini Probleme mit der i2c Anbindung zu geben. Daher hier die Möglichkeit per spi und spl.

wifi:
  networks:
    - ssid: "EUERWLAN"          
      password: "EUERWLANKENNWORT"
  ap:
    ssid: ${devicename}


captive_portal:

substitutions:
  devicename: tagreader
  friendly_name: TagReader

esphome:
  name: $devicename
  platform: ESP8266
  board: d1_mini

  on_boot:
    priority: -10
    then:
    - wait_until:
        api.connected:
    - logger.log: API is connected!
    - rtttl.play: "success:d=24,o=5,b=100:c,g,b"
    - light.turn_on:
        id: activity_led
        brightness: 100%
        red: 0%
        green: 0%
        blue: 100%
        flash_length: 500ms

switch:
- platform: template
  name: "${friendly_name} Buzzer EIN"
  id: buzzer_enabled
  icon: mdi:volume-high
  optimistic: true
  restore_state: true
- platform: template
  name: "${friendly_name} LED EIN"
  id: led_enabled
  icon: mdi:alarm-light-outline
  optimistic: true
  restore_state: true


logger:


api:
  password: "EUERAPIPASSWORT"
  services:
  - service: rfidreader_tag_ok
    then:
    - rtttl.play: "beep:d=16,o=5,b=100:b"

  - service: rfidreader_tag_ko
    then:
    - rtttl.play: "beep:d=8,o=5,b=100:b"

  - service: play_rtttl
    variables:
      song_str: string
    then:
    - rtttl.play: !lambda 'return song_str;'

  - service: write_tag_random
    then:
    - lambda: |-
        static const char alphanum[] = "0123456789abcdef";
        std::string uri = "//www.home-assistant.io/tag/";
        for (int i = 0; i < 8; i++)
          uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
        uri += "-";
        for (int j = 0; j < 3; j++) {
          for (int i = 0; i < 4; i++)
            uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
          uri += "-";
        }
        for (int i = 0; i < 12; i++)
          uri += alphanum[random_uint32() % (sizeof(alphanum) - 1)];
        auto message = new nfc::NdefMessage();
        message->add_uri_record(uri);
        ESP_LOGD("tagreader", "Writing payload: %s", uri.c_str());
        id(pn532_board).write_mode(message);
  - service: write_tag_id
    variables:
      tag_id: string
    then:
    - lambda: |-
        auto message = new nfc::NdefMessage();
        std::string uri = "//www.home-assistant.io/tag/";
        uri += tag_id;
        message->add_uri_record(uri);
        id(pn532_board).write_mode(message);
  - service: clean_tag
    then:
    - lambda: 'id(pn532_board).clean_mode();'

  - service: cancel_writing
    then:
    - lambda: 'id(pn532_board).read_mode();'

ota:
  password: "EUEROTAPASSWORT"

spi:
  clk_pin: D0
  miso_pin: D1
  mosi_pin: D2

pn532_spi:
  cs_pin: D3
  update_interval: 1s
  id: pn532_board
  on_tag:
    then:
    - homeassistant.tag_scanned: !lambda |
        if (!tag.has_ndef_message()) {
          ESP_LOGD("tagreader", "No NDEF");
          return x;
        }
        auto message = tag.get_ndef_message();
        auto records = message->get_records();
        for (auto &record : records) {
          std::string payload = record->get_payload();
          size_t pos = payload.find("//www.home-assistant.io/tag/");
          if (pos != std::string::npos) {
            return payload.substr(pos + 34);
          }
        }
        ESP_LOGD("tagreader", "Bad NDEF, fallback to uid");
        return x;
    - if:
        condition:
          switch.is_on: buzzer_enabled
        then:
        - rtttl.play: "success:d=24,o=5,b=100:c,g,b"
    - if:
        condition:
          switch.is_on: led_enabled
        then:
        - light.turn_on:
            id: activity_led
            brightness: 100%
            red: 0%
            green: 100%
            blue: 0%
            flash_length: 500ms

output:
- platform: esp8266_pwm
  pin: D7
  id: buzzer

binary_sensor:
  - platform: status
    name: "${friendly_name} Status"

rtttl:
  output: buzzer

light:
- platform: fastled_clockless
  chipset: WS2812
  pin: D8
  default_transition_length: 10ms
  num_leds: 1
  rgb_order: GRB
  id: activity_led
  name: "${friendly_name} LED"
  restore_mode: ALWAYS_OFF

Der Anschluss der Kabel an den D1 Mini bitte wie folgt abändern:

SCK -> D3
MISO -> D1
MOSI -> D2
SS-> D0
VCC -> 5V
GND -> G

Buzzer -> D7
LED -> D8

Ich hoffe Ihr hatte Spaß mit dieser Anleitung. Wenn Ihr fragen haben solltet, dann schreibt mir eine Mail an info[at]smart-4u.de oder folgt mir dazu doch einfach auf Instagram.

Wenn ich Euch helfen konnte und Ihr mich unterstürtzen wollt, dann würde ich mich freuen, wenn Ihr mal bei meiner Amazon-Wunschliste vorbeischaut.

Alles kann aber nichts muss!

 

9 KOMMENTARE
  • Ronny
    Antworten

    Hallo,

    eine sehr schöne Anleitung, danke dafür.
    Wäre es auch möglich, das Ganze batterie-/akkubetrieben zu bauen? Benötige es für eine Stelle, an welcher kein permanenter Stromanschluss zur Verfügung steht. Bestenfalls für Außen geeignet?

    VG
    Ronny

    1. Marvin
      Antworten

      Hallo Ronny!

      Danke für die Blumen. Ein Batterie betrieb wird schwierig zu realisieren sein, da der ESP ständig mit dem WLAN in Verbindung ist und der Sensor ja auch dauerhaft mit Strom versorgt werden muss. Man könnte das mit Akkus und einem Solar Panel versuchen. Und wenn Du weißt, dass der Sensor nur zu bestimmten Tageszeiten laufen muss, könnte man einen deepsleep einbauen um so Strom zu sparen.

  • sascha
    Antworten

    Hallo,

    kann mal anstelle von einem RFID Chip auch die Apple Watch davor halten?

    1. Marvin
      Antworten

      Hallo Sascha, grundsätzlich sollte das funktionieren, wenn Du eine Karte in deiner Watch hinterlegt hast. Getestet habe ich das aber noch nicht. Apple ist da ja immer ein bisschen eigen.

  • Daniel
    Antworten

    Servus,

    was muss ich denn machen, damit ich das auch mit einem RFID-RC522 zum laufen bekomme? Ich verzweifle gerade.

    1. Marvin
      Antworten

      Moin Daniel!

      Mit dem Sensor habe ich mich noch nicht auseinander gesetzt. Aber vielleicht hilft Dir das hier weiter.

      Gruß

      1. Daniel
        Antworten

        OK Danke. kann ich denn das sensor einfach so in deinem Script Tauschen. Sorry bin neu in dem Thema

        1. Marvin
          Antworten

          Hey Daniel!

          Grundsätzlich müsstest Du das Script natürlich Deinem Sensor anpassen. Und die Verdrahtung ist auch anders als auf meinem Schema. Wenn Du noch zwei Wochen Zeit hast, dann schreibe ich dazu einen Tutorial.

          1. Daniel

            Ja habe ich 🙂 super vielen Dank

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert