ESP Home key collector

Hello, I have a problem, if the Key Collector has created the same code for me twice, I don’t get a separate output.
this means that my automation cannot be triggered. can you help me

What key collector?

the one that is part of esphome…
The key collector is pretty sweet too. You can use any keypad that uses wiegand26/34 output(which most do) and integrate that into esphome. I installed this one on my garage door. Each person has a code and an rfid tag. I can see the history of who last opened/closed the door, disable or give access to new tags or codes from HA. The other cool thing is you can fire automation’s, toggle individual things, disable your alarm, etc. all from the keypad, It’s pretty sweet I love it.
https://www.amazon.com/dp/B088M5ZZCV?psc=1&ref=ppx_yo2ov_dt_b_product_details
Sounds like they just copied and pasted the example config 2 times without giving each a unique ID

1 Like

You have to be more specific. post your code. what keypad? what are you trying to do? You gotta provide information or else no one knows what your talking about and they definately can’t help you. Did you make 2 key collectors in your config? do you have 2 keypads?

1 Like

Weird that this component isn’t listed on the main docs index https://esphome.io/

Thanks :slight_smile:

ya, i agree. I regularly browse through the esphome components to keep things fresh and to stimulate new ideas and I stumbled across it by accident. The key collector and the wiegand26 component open a lot of doors for alarm systems or other things and you hardly see them discussed in the main channels and this is probably the main reason, no one knows about it.

1 Like

this is my config. my problem are, the code doesn’t change if I enter it twice, so no automation can be triggered

key_collector:
  - id: pincode_reader
    source_id: mykeypad
    min_length: 4
    max_length: 8
    end_keys: "#"
    end_key_required: True
    back_keys: "*"
    clear_keys: "C"
    allowed_keys: "0123456789"
    timeout: 4s
    on_progress:
      - logger.log:
          format: "input progress: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
       
    on_result:
       - text_sensor.template.publish:
          id: text_sensor_pincode
          state: !lambda 'return x.c_str();'   
    on_timeout:
      - logger.log:
          format: "input timeout: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]

text_sensor:
  - platform: template
    name: "PIN Code"
    id: text_sensor_pincode

  - platform: template
    name: "TAG Code"
    id: text_sensor_tagcode

i don’t understand what you mean, “The code doesn’t change if I enter it twice” Are you talking about the text sensor? that isn’t changing and it’s showing the code twice? If that’s what your talking about, it’s because your using a text sensor and you need to be using a regular sensor. Each time a new code is entered, the state of the sensor will be that code and the last code will just go into history.

sensor:
  - platform: template
    name: "PIN Code"
    id: text_sensor_pincode

  - platform: template
    name: "TAG Code"
    id: text_sensor_tagcode

here is mine if it helps. I really dont understand what the issue is your having. I don’t see any automations that are supposed to be triggered by the code and it doesn’t do anything except display the numbers(code) in a text sensor, i can’t tell if the problem is there or the key collector.

key_collector:
  - id: pincode_reader
    source_id: mykeypad
    min_length: 4
    max_length: 5
    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)" ]    

sensor. The state of the sensor is where automations are toggled and also where information like “Last Tag Scanned” would come from, it’s published from the sensor value then to the text_sensor.

sensor:

  - platform: template
    name: Keypad Code
    id: keyCode    
    on_value:
      - if:
          condition:
            - lambda: 'return id(keyCode).state == 67345433;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Justin's Tag"
      - if:
          condition:
            - lambda: 'return id(keyCode).state == 1454;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Justin's Code"          

      - if:
          condition:
            - lambda: 'return id(keyCode).state == 64234343;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Paula's Tag"
      - if:
          condition:
            - lambda: 'return id(keyCode).state == 2323;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Paula's Code"          

      - if:
          condition:
            - lambda: 'return id(keyCode).state == 634343;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Mike's Tag"
         
      - if:
          condition:
            - lambda: 'return id(keyCode).state != 6443433;' 
            - lambda: 'return id(keyCode).state != 6434334;'
            - lambda: 'return id(keyCode).state != 6753434;'
            - lambda: 'return id(keyCode).state != 10232;'
            - lambda: 'return id(keyCode).state != 19343;'
          then:
            - text_sensor.template.publish:
                id: last_user
                state: "Invalid User Access"


text sensor

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

please can you write the full yaml code? my replaced code shows errors…:frowning:

what error?

The errors tell you what the problem is, they’re very specific. You need to post the errors so I know what it is. You really need to make an effort to learn how to read the error and fix what it is telling you needs fixed. This is how you learn and get better. Just copying and pasting someone else’s yaml doesn’t teach you anything.

i tried your code in a new yaml. …

esphome:
  name: wiegandtest
  friendly_name: wiegandtest

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xIfnyI5kmciRt6h4ziXGXoFm2gWdIpG+xV3TLluZb3Q="

ota:
  password: "f9000cda825093900091c0c949e1666b"

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

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

captive_portal:
    
wiegand:
  - id: mykeypad      
    d0: GPIO5
    d1: GPIO4
    on_key:
      - lambda: ESP_LOGI("KEY", "received key %d", x);
    on_tag:
      then:
      - homeassistant.tag_scanned: !lambda 'return x;'
    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: 5
    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)" ]

sensor:

  - platform: template
    name: Keypad Code
    id: keyCode    
    on_value:
      - if:
          condition:
            - lambda: 'return id(keyCode).state == 67345433;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Justin's Tag"
      - if:
          condition:
            - lambda: 'return id(keyCode).state == 1454;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Justin's Code"          

      - if:
          condition:
            - lambda: 'return id(keyCode).state == 64234343;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Paula's Tag"
      - if:
          condition:
            - lambda: 'return id(keyCode).state == 2323;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Paula's Code"          

      - if:
          condition:
            - lambda: 'return id(keyCode).state == 634343;' 
          then:  
            - switch.toggle: OvrHead
            - text_sensor.template.publish:
                id: last_user
                state: "Mike's Tag"
         
      - if:
          condition:
            - lambda: 'return id(keyCode).state != 6443433;' 
            - lambda: 'return id(keyCode).state != 6434334;'
            - lambda: 'return id(keyCode).state != 6753434;'
            - lambda: 'return id(keyCode).state != 10232;'
            - lambda: 'return id(keyCode).state != 19343;'
          then:
            - text_sensor.template.publish:
                id: last_user
                state: "Invalid User Access"
  - platform: template
    name: Last User
    id: last_user
    icon: mdi:clock-start
INFO ESPHome 2023.5.5
INFO Reading configuration /config/esphome/wiegandtest.yaml...
Failed config

sensor.template: [source /config/esphome/wiegandtest.yaml:69]
  platform: template
  name: Keypad Code
  id: keyCode
  on_value: 
    - if: 
        condition: 
          - lambda: return id(keyCode).state == 67345433;
        then: 
          - 
            Unable to find action with the name 'switch.toggle'.
            switch.toggle: OvrHead
          - text_sensor.template.publish: 
              id: last_user
              state: Justin's Tag
    - if: 
        condition: 
          - lambda: return id(keyCode).state == 1454;
        then: 
          - switch.toggle: OvrHead
          - text_sensor.template.publish: 
              id: last_user
              state: Justin's Code
    - if: 
        condition: 
          - lambda: return id(keyCode).state == 64234343;
        then: 
          - switch.toggle: OvrHead
          - text_sensor.template.publish: 
              id: last_user
              state: Paula's Tag
    - if: 
        condition: 
          - lambda: return id(keyCode).state == 2323;
        then: 
          - switch.toggle: OvrHead
          - text_sensor.template.publish: 
              id: last_user
              state: Paula's Code
    - if: 
        condition: 
          - lambda: return id(keyCode).state == 634343;
        then: 
          - switch.toggle: OvrHead
          - text_sensor.template.publish: 
              id: last_user
              state: Mike's Tag
    - if: 
        condition: 
          - lambda: return id(keyCode).state != 6443433;
          - lambda: return id(keyCode).state != 6434334;
          - lambda: return id(keyCode).state != 6753434;
          - lambda: return id(keyCode).state != 10232;
          - lambda: return id(keyCode).state != 19343;
        then: 
          - text_sensor.template.publish: 
              id: last_user
              state: Invalid User Access

so, it sais " Unable to find action with the name ‘switch.toggle’." The problem is with switch.toggle. You don’t have a switch defined in your yaml so there’s no switch to toggle.

It is fundamental Home Assistant behavior that triggers only occur when a state changes. So if the second entry is the same, there is no change and no trigger. That means you need to find a way to clear the entry some time after it was set (or prior to the start of new data entry).

you have a “sensor” “key_collector” and “wiegand” defined in the code.
Here, it’s saying “If” the condition is True “then” switch.toggle(OvrHead). There’s no switch in your code with the ID OvrHead so that’s why there’s an error.

 on_value: 
    - if: 
        condition: 
          - lambda: return id(keyCode).state == 67345433;
        then: 
          - 
            Unable to find action with the name 'switch.toggle'.
            switch.toggle: OvrHead
          - text_sensor.template.publish: 
1 Like

The problem is he doesn’t have a switch to toggle and he’s calling a switch.toggle action.

1 Like

This has nothing to do with Home Assistant and the way it handles triggers. This is my config and i can assure you there’s nothing wrong with how the triggers are called and function. Esphome works independent of HA and you seem to be conflating the two when they are seperate.

Your config requires a switch, but his original implementation did not. His original implementation had the problem I mentioned. Seems you have a different way to work around it, but I wasn’t talking about that.

the original config had nothing at all. There were no triggers, conditions, and no action other than returning the keycode as a tag scan event. The “original config” is the old config anyway and he has a different config, making your point irrelevant either way.