[TUTO] Contrôle d'accès clavier Wiegand + ESP32 et ESPHome

Bonjour à tous,

Après avoir cherché comment faire, puis réalisé un contrôle d’accès par clavier, voici un tuto qui aidera je pense pas mal de personnes. Car tout est très souvent pensé pour Arduino alors qu’ESPHome commence à devenir très intéressant et intègre de plus en plus de choses en natif , comme en témoigne la documentation esphome.io.

Le projet vient à la base d’une problématique d’un ami, il souhaitait pouvoir changer facilement de code pour son logement Airbnb entre deux locataires. Il a essayé plusieurs claviers en Tuya mais qui fonctionnaient mal, et dépendants du cloud en plus et il m’en a parlé après coup…

L’idée est donc de changer de code en un appui depuis le smartphone sous Home Assistant.

J’utilise dans ce projet un script qui génère un code aléatoire à 4 chiffres, qui apparait sur le lovelace et qui est envoyé en notification, de manière à pouvoir faire un copier/coller ou partager pour le nouvel arrivant Airbnb.

La saisie du code a pour effet ici d’actionner un volet roulant, mais cela fonctionne tout aussi bien pour commander un solénoïde ou une porte avec des serrures magnétiques (dans ce cas là, le relais fonctionnera à l’envers tout simplement : alimenté en permanence (NC) puis coupé pour l’ouverture)

Pour compliquer la chose, mon ami à deux accès différents qu’il voulait dissocier, (donc avec 2 codes différents) mais avec le même principe : un accès par volet roulant.

J’ai donc réalisé tout ce projet en double…

Matériel nécessaire :

  • Un ESP32 (5 broches seront utilisées à vous de voir quel modèle vous préférez, un Wemos D1 mini peut convenir si vous recherchez la miniaturisation.

  • Un relais 5v

OPTION en fonction de votre configuration et de vos restrictions sur place :

Un abaisseur & régulateur de tension 12v vers 5v


Si votre clavier fonctionne en 12v, il vous faudra du 12v et du 5v.

• Une pince et des connecteurs Dupont et du fil.
Si vous commencez à faire des montages et que vous vous y mettez sérieusement, c’est un kit indispensable pour moins de 15€.

Choisissez votre clavier en conséquence. Dans mon cas, j’ai fait mon premier proto avec un clavier déjà en possession par mon ami (le rectangulaire couleur silver) C’est le seul du lot qui était au protocole Wiegand, en attendant le deuxième clavier que j’ai acheté pour lui pour son deuxième accès suite à des recherches, en particulier après avoir vu une vidéo de la chaine Youtube «Usine a gaz domotique »
Celle-ci pour être précis : https://www.youtube.com/watch?v=9cibqWgKid4&t=228s

Nous aurons besoin donc de 3 GPIO. 1 pour la commande de relais et 2 GPIO pour l’échange de données avec le clavier.

PARTIE HARDWARE

Tout est connecté de la manière suivante :

GPIO 4 = D0

GPIO5 = D1

GPIO23 = commande du relais

3.3v et GND de l’ESP respectivement sur les broches du relais.

Rappel, il est préférable d’utiliser les broches 4,5 puis les broches de 18 à 33 pour un ESP32.

Avec tout de même une réserve sur le GPIO 5 qui prend une impulsion PWM au démarrage de l’ESP.

Cela peut être voulu selon les cas, à vous de voir. (un reboot peut actionner le relais par exemple si vous choisissez le GPIO5 pour le relais, cela peut être pratique en cas d’urgence)

J’ai vivement suggéré à mon ami l’emploi d’onduleur dans ce cas typique. Ce serai dommage que les locataires ne puissent pas entrer en cas de coupure de courant, à 04h du matin, sous une pluie battante… ^^

PARTIE SOFTWARE

Vous verrez sur la vidéo, je pars d’une installation propre d’Home Assistant et de tout ce qui est nécessaire (MQTT, ESPHome…)
Je pars d’une installation propre, avec un RPI 4 que j’avais déjà et mon ancien SSD, même si ça peut paraître overkill c’est préférable par rapport à une Micro SD. Je ne joue pas avec ça, il n’est pas question que ça plante dans 6 mois ou 1 ans, sachant que ça va être sollicité.

Le script qui génère un code à 4 chiffres aléatoire.

alias: Générer un code à 4 chiffres Airbnb
sequence:
  - data:
      entity_id: input_text.code_securite
      value: "{{ '%04d' | format(range(10000) | random) }}"
    action: input_text.set_value
  - action: notify.persistent_notification
    metadata: {}
    data:
      message: Le code généré est {{ states('input_text.code_securite') }}
description: ""

La déclaration à faire dans le configuration.yaml

input_text:
  code_securite:
    name: Code Généré Airbnb
    initial: "0000"
    max: 4

IMPORTANT C’est le code par défaut au démarrage d’Home Assistant, donc en cas de coupure de courant ou après une mise à jour et redémarrage. A personnaliser en connaissance de cause, car tant que le script ne sera pas exécuté c’est ce code qui fonctionnera. Sinon, supprimez cette ligne (initial: « 0000 »), de cette façon le code généré précédemment sera conservé, même après un redémarrage.

L’automatisation pour vérifier le CODE tapé au clavier

alias: Vérification du code saisi Airbnb
description: ""
triggers:
  - trigger: state
    entity_id:
      - sensor.clavierbnb_code_clavier_saisi
conditions:
  - condition: template
    value_template: >-
      {{ is_state('sensor.clavierbnb_code_clavier_saisi',
      states('input_text.code_securite')) }}
actions:
  - type: turn_on
    device_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    entity_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    domain: switch

L’automatisation pour vérifier le TAG lu (évidemment à adapter à l’ID unique de votre tag)

alias: Vérification du tag lu Airbnb
description: ""
triggers:
  - trigger: state
    entity_id:
      - sensor.clavierbnb_tag_lu
    to: "xxxxxxxx"
actions:
  - type: turn_on
    device_id: xxxxxxxxxxxxxxxxxxxxxxxxxxx
    entity_id: xxxxxxxxxxxxxxxxxxxxxxxxxxx
    domain: switch

Pour finir, le code yaml pour l’ESP32 à flasher

esphome:
  name: clavierbnb
  friendly_name: Clavier Airbnb
  platform: ESP32
  board: esp32dev

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

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

  # Optional manual IP
  manual_ip:
    static_ip: 192.168.1.69
    gateway: 192.168.1.1
    subnet: 255.255.255.0  

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Clavierbnb Fallback Hotspot"
    password: "xxxxxxxxxxxxxxxxxxxxxxxxx"

web_server:
  port: 80

wiegand:
  - id: clavierbnb
    d0: GPIO4
    d1: GPIO5
    on_key:
      - lambda: ESP_LOGI("KEY", "received key %d", x);
    on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
      - text_sensor.template.publish:
          id: tag_lu
          state: !lambda "return x.c_str();"
      # Enregistre également dans le log
      - logger.log:
          format: "Tag lu: '%s'"
          args: [ 'x.c_str()' ]
      # Attendre 5 secondes, puis réinitialiser l'entité tag_lu à une valeur neutre
      - delay: 5s
      - text_sensor.template.publish:
          id: tag_lu
          state: "Aucun tag"          
    on_raw:
      - lambda: ESP_LOGI("RAW", "received raw %d bits, value %llx", bits, value);

# Déclaration d'un text sensor
text_sensor:
  - platform: template
    name: "Code clavier saisi"  
    id: code_clavier
  - platform: template
    name: "Tag lu"
    id: tag_lu

# Définition du key collector
key_collector:
  - id: pincode_reader
    source_id: clavierbnb
    min_length: 4
    max_length: 4
    end_keys: "#"
    end_key_required: true
    back_keys: "*"
    clear_keys: "C"
    allowed_keys: "0123456789"
    timeout: 5s
    on_result:
      # Met à jour le text_sensor avec le code saisi
      - text_sensor.template.publish:
          id: code_clavier
          state: !lambda "return x.c_str();"
      # Enregistre également dans le log
      - logger.log:
          format: "input result: '%s'"
          args: [ 'x.c_str()' ]
      # Attendre 5 secondes, puis réinitialiser l'entité code_clavier à une valeur neutre
      - delay: 5s
      - text_sensor.template.publish:
          id: code_clavier
          state: "Aucun code"          
    on_timeout:
      - logger.log:
          format: "input timeout: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]

switch:
  - platform: gpio
    pin: GPIO23
    inverted: True
    id: relais
    name: "Ouvrir le volet Airbnb"
    icon: "mdi:door-closed-lock"
    on_turn_on:
    - delay: 1s
    - switch.turn_off: relais

mqtt:
  broker: "192.168.1.68"  # Replace with your MQTT broker IP address
  username: "mqtt"    # Optional: add your broker's username
  password: "xxxxxxxxxxxxxxx"  # Optional: add your broker's password

Evidemment à adapter avec vos paramètres. J’ai fait le choix d’une IP fixe.

Également le MQTT qui n’est pas nécessaire au fonctionnement dans l’état actuel des choses, mais tout de même mieux pour l’avenir.

Enfin j’ai fait le choix ici de réinitialiser l’état des sensors après 5 secondes (à adapter selon chacun) car j’ai essayé 3 façons de le faire dans les scripts & automatisations sans que ça ne fonctionne…

Cela est nécessaire car l’automatisation n’à lieu que quand il y a un changement d’état du sensor.

Par conséquent le code n’est pas reconnu plusieurs fois consécutives lorsqu’il est tapé au clavier alors que c’est toujours le même, mais seulement 1 fois. Cela est valable pour le tag RFID également.

Si vous ne le faites pas, vous serrez obligé de taper un code aléatoire, puis de retaper le code « officiel » C’est vraiment dommage.

6 « J'aime »