Wiegand Code Writing ESPHome + Home Assistant

Can you post up what is in your esphome Yaml? I am in the same boat as you and trying to put together a reader with ESPHome and not having much luck hehe.

Yeah no problem! Note: it’s not complete, it’s probably deemed as “sloppy” by the pro’s, and there’s probably more efficient ways to do what I did, but right now, it works. My only probably is deep sleep. In the early mornings when my ex-wife brings my kids over before school, they have to put in a code, wait a few seconds, then put in their code again and it works. Slight nuisance, but perfectly usable.

You’ll have to make a few input_booleans and text_inputs in HA, then link to them in ESPHome (this is the inefficient part, I’ve been told). My input texts are called input_text.dog_walker_code_1 (and 2 and 3). Then I have toggles that I brought over into ESPHome called “garage_code_immediate_family”. These toggles allow me to turn off any “group” of codes at a moment’s notice if I want to. The input texts allow me to make variable codes for the dog walkers on a moment’s notice as well. Here’s the code:

esphome:
  name: garage-keypad
  friendly_name: Garage Keypad

#  on_boot:
#    priority: -100
#    then:
#      - wait_until:
#          condition:
#            api.connected:
#      - delay: 5s
#      - deep_sleep.prevent: deep_sleep_1

deep_sleep:
  id: deep_sleep_1
  run_duration: 720min
  sleep_duration: 5s

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "j2hoiNUzB6TKBXIVVhQ4Y0okXdfoVdz4R5z+ccF+Ce8="

ota:
  password: "a31a6bcb12b53a7b733c8f757004d3c8"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  fast_connect: true

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Garage-Keypad Fallback Hotspot"
    password: "justingoeden"



captive_portal:




binary_sensor:
  - platform: homeassistant
    name: "Immediate Family Entry"
    id: immediatefamilyentry
    entity_id: input_boolean.garage_code_immediate_family

  - platform: homeassistant
    name: "Guests Family Entry"
    id: guestsentry
    entity_id: input_boolean.garage_code_guests

  - platform: homeassistant
    name: "Dog Walkers Entry"
    id: dogwalkersentry
    entity_id: input_boolean.garage_code_dog_walkers

  - platform: status
    id: keypad_status
    name: Garage Keypad Status 


      

switch:
  - platform: template  
    id: OvrHead
    optimistic: true 
    on_turn_on:
      - homeassistant.service:
          service: cover.toggle
          data: 
            entity_id: cover.garage_door
      - delay: 1s
      - switch.turn_off: OvrHead
      
  - platform: template
    id: dog1match
    optimistic: true
    name: "Dog Walker Code 1 Match"
    lambda: |-
      if (id(keyCode).state == id(dogwalkercode1).state) {
        return true; }
        else {
          return false;
      }  
    on_turn_on:
      - if:
          condition:
            - binary_sensor.is_on: dogwalkersentry
          then:
            - switch.turn_on: OvrHead
            - delay: 1s
            - sensor.template.publish:
                id: keyCode
                state: "0000"     
            - text_sensor.template.publish:
                id: last_user
                state: "Dog Walker Custom Code"  
  - platform: template
    id: dog2match
    optimistic: true
    name: "Dog Walker Code 2 Match"
    lambda: |-
      if (id(keyCode).state == id(dogwalkercode2).state) {
        return true; }
        else {
          return false;
      }  
    on_turn_on:
      - if:
          condition:
            - binary_sensor.is_on: dogwalkersentry
          then:
            - switch.turn_on: OvrHead
            - delay: 1s
            - sensor.template.publish:
                id: keyCode
                state: "0000"     
            - text_sensor.template.publish:
                id: last_user
                state: "Dog Walker Custom Code"  
  - platform: template
    id: dog3match
    optimistic: true
    name: "Dog Walker Code 3 Match"
    lambda: |-
      if (id(keyCode).state == id(dogwalkercode3).state) {
        return true; }
        else {
          return false;
      }  
    on_turn_on:
      - if:
          condition:
            - binary_sensor.is_on: dogwalkersentry
          then:
            - switch.turn_on: OvrHead
            - delay: 1s
            - sensor.template.publish:
                id: keyCode
                state: "0000"     
            - text_sensor.template.publish:
                id: last_user
                state: "Dog Walker Custom Code"  

button:
  - platform: restart
    name: "Keypad Restart"
  - platform: safe_mode
    name: "Keypad (Safe Mode)"  
 

text_sensor:  

  - platform: template
    name: Uptime Garage Keypad
    id: uptime_human_wg26
    icon: mdi:clock-start

  - platform: template
    name: Last User
    id: last_user
    icon: mdi:clock-start   


    
sensor:

  - platform: homeassistant
    name: "Dog Walker's Code 1"  
    id: dogwalkercode1
    entity_id: input_text.dog_walker_code_1

  - platform: homeassistant
    name: "Dog Walker's Code 2"  
    id: dogwalkercode2
    entity_id: input_text.dog_walker_code_2

  - platform: homeassistant
    name: "Dog Walker's Code 3"  
    id: dogwalkercode3
    entity_id: input_text.dog_walker_code_3

  - platform: template
    name: Keypad Code
    id: keyCode    
    on_value:
 
      - if:
          condition:
            - binary_sensor.is_on: immediatefamilyentry
            - lambda: 'return id(keyCode).state == 9012;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Brittany's Code"
      - if:
          condition:
            - binary_sensor.is_on: immediatefamilyentry
            - lambda: 'return id(keyCode).state == 1948;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Justin's Code"          
      - if:
          condition:
            - binary_sensor.is_on: immediatefamilyentry
            - lambda: 'return id(keyCode).state == 1224;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Jack's Code"
      - if:
          condition:
            - binary_sensor.is_on: immediatefamilyentry
            - lambda: 'return id(keyCode).state == 3025;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Simons's Code"    
#--------------------------Jack Simon Caiti Donna Hunter Lindsey codes-------------------------------
      - if:
          condition:
            - binary_sensor.is_on: guestsentry
            - lambda: 'return id(keyCode).state == 1017;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Caiti's Code"

      - if:
          condition:
            - binary_sensor.is_on: guestsentry
            - lambda: 'return id(keyCode).state == 5028;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Donnas's Code"

      - if:
          condition:
            - binary_sensor.is_on: guestsentry
            - lambda: 'return id(keyCode).state == 1006;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Hunter's Code"   

      - if:
          condition:
            - binary_sensor.is_on: guestsentry
            - lambda: 'return id(keyCode).state == 2020;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Lindsey's Code"                 
      - if:
          condition:
            - lambda: 'return id(keyCode).state != 9012;' 
            - lambda: 'return id(keyCode).state != 1948;' 
            - lambda: 'return id(keyCode).state != 1224;'
            - lambda: 'return id(keyCode).state != 3025;'
            - lambda: 'return id(keyCode).state != 1017;'
            - lambda: 'return id(keyCode).state != 5028;'
            - lambda: 'return id(keyCode).state != 1006;'
            - lambda: 'return id(keyCode).state != 2020;'   
            - lambda: 'return id(keyCode).state != 0000;' 
          then:
            - text_sensor.template.publish:
                id: last_user
                state: "Invalid User Access"



  - platform: wifi_signal    
    id: wifi_signal_db
    update_interval: 300s
    entity_category: "diagnostic"

  - platform: copy 
    source_id: wifi_signal_db
    name: "WiFi Signal Keypad"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    entity_category: "diagnostic"
    id: wifiSignalWG26

  - platform: uptime #Uptime in Seconds
    name: Garage Keypad Uptime
    id: uptime_sensor_wiegand
    update_interval: 240s
    internal: True
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human_wg26
            state: !lambda |-
              int seconds = round(id(uptime_sensor_wiegand).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? String(days) + "d " : "") +
                (hours ? String(hours) + "h " : "") +
                (minutes ? String(minutes) + "m " : "") +
                (String(seconds) + "s")
              ).c_str();

wiegand:
  - id: mykeypad
    d0: GPIO33
    d1: GPIO32
    on_key:
      - lambda: ESP_LOGI("KEY", "received key %d", x);
    on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
      - sensor.template.publish:
         id: keyCode
         state: !lambda "return parse_number<float>(x).value();"  
      - homeassistant.tag_scanned: !lambda 'return x.c_str();'
          
    on_raw:
      - lambda: ESP_LOGI("RAW", "received raw %d bits, value %llx", bits, value);

key_collector:
  - id: pincode_reader
    source_id: mykeypad
    min_length: 4
    max_length: 4
    end_keys: "#"
    end_key_required: true
    clear_keys: "*"
    allowed_keys: "0123456789"
    timeout: 5s
    on_progress:
      - logger.log:
          format: "input progress: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
    on_result:      
      then:
        - sensor.template.publish:
            id: keyCode
            state: !lambda "return parse_number<float>(x).value();"         
                
    on_timeout:
      - logger.log:
          format: "input timeout: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]      

Good luck!

1 Like

Thanks! Do you have it deep sleep because it’s on a battery?

Oh shoot, no. I had been playing around with things and meant to delete that code. You don’t need that in there if you’re hardwired. I had been fighting with “it” falling asleep, and I think that my actual Wiegand device is falling asleep. So just today I removed the deep sleep code.

On another note, I can’t get this to work for the life of me. I’ve tried several different readers and even switched to a new one as a test that came with it’s own tags in case that was the issue and still getting the message in ESP home logs: Image 2023-10-18 at 7.19.27 PM

I’m not sure if it’s my wiring, yaml or what. My green is connected to d0, white to d1. I’ve tried with and without a ground to the board and that does nothing. Here is my yaml: Image 2023-10-18 at 7.20.06 PM. Any ideas?

Are you also using the keylogger function from ESPHome?

If you have the option to hardwire it, I would. Your going to have to press a key or use some method as a an interrupt to wake it up and then there’s going to be a delay before it’s actually able to read and transmit a code or tag scan and most importantly batteries die and you risk locking yourself out.

I think there’s a misunderstanding, there’s no batteries anywhere. I have a 12 volt power supply which is supplying the wiegand controller And it branches off to a voltage regulator that outputs 4.89 volts straight to the ESP32.

What kind of box and board is that? I’ve been looking at a bunch of different solutions (mostly junction boxes) for getting the ESP8266, buck relay and misc wiring in one place. Also what kind of board is that you have the ESP32 on? Did you solder the pins to it so you could simply screw the wires in? I like that.