ESPHome + SX1509 keypad +RFID as garage opener

I’m searching a way to integrate opening my garage doors with ESPHome (and integrate it in HA, sure). For this purpose i bought SX1509 I/O expander, which can run a keypad and RC522 RFID tag reader. I intend to have RFID or a code for opening garage. Main interface will be ESP201 (ESP8266 chip).

But, here i’d need some suggestions and help. My goal is:

  • possibility to open doors via HA interface (that part is not a problem - i already have that via a relay)
  • i guess (?) that a good idea is that ESP201 opens garage independently from HA, so within ESPHome module (if network connection goes down i’ll still be able to open door),

…so here is where i’m stuck. I guess that RFID part can be done (all tags would have to be stored inside ESP201), but how do i write a part for opening with code? If i make binary sensors for each number (and #, *) i get that in my HA as separate numbers. What i’d like to do it enter 4-6 digit code, confirm it with ‘#’ and if it’s correct trigger a relay, so i guess i’d need some kind of “buffer” to store temporary entered numbers. Any unfinished code should also be cleared after, say 5 seconds .

What do you guys think? Is it really necesarry to make it undependently from HA (so within ESPHome) or not? My network is (so far) pretty stable, i don’t recall any blackouts…
It would also be a good practice to add any additional users (code or RFID) at a later time when necesarry.

Can all this be done at all or it’s too much for a beginner user like me? I did quite some search, but can’t find anything similar. Nearest thing with keypad i found is “alarm panel”, maybe i could use that…?

Any advice would be very welcome.

I spotted this recently https://github.com/Syralist/esphomekeypad

Aha… looks promising… .but… .now i have to learn how to add this custom component to my HA…(i never done this before)…

EDIT: ok, it seems that i managed to add libraries (copied *.h into esphome folder), but i just can’t find how to define row and column pins (D1 through D7) in esphome yaml…?

I don’t think you have to define them in the yaml file. If you are not happy with the defaults you can change the .h file (esphomekeypad/keypad_sensor.h at 6696ac7511392915fed95cb44f88aadee3a2887d · Syralist/esphomekeypad · GitHub)

Well, for my ESP8266 board i get an error if i leave defaults. When i removed “D” then error went away, but then a new set of “problems” arise: i have hardly enough pins on ESP8266, since SCL and SDA will be used for sensors, then i’m not quite sure if, say, GPIO10 is same as “10”, because keyboard itself doesn’t work, as i wouldn’t press any button…
(Best solution would be to define pins on I/O board, like sx1509, MCP23017…)

I tried another option: keypad component - it’s similar as above component, but at the moment i failed there, too. I’m just not skilled enough, as it seems and guides for HA noobs are practically impossible to find, all add-ons are written with presumption that all people know (almost) everything… In this keypad component i’m stuck at ESPHome yaml creating, where i have an error “component keypad not found”. I missed something, sure. But what…?

Docs: Configuration Types — ESPHome

I do not think you need any extender. 2 pins for I2C for the RC522 and 7 pins (4x3 matrix) for the keypad. Or have I missed something?

I wasn’t familiar with the esp201 so I want by a pinout I found on the net

Thanks for all info!
Theoretically there ARE enough pins for4x3 matrix. Some of them (colored light blue) are used for flash, but there are 7+2 available, sure. BUT… (of course there’s “but”). in practice some of those pins doesn’t work well with being OUT and some doesnt’ work well being IN - all those that must be connected to GND or +Vcc at bootup work “funny”. So, best i managed to do is to work all digits except number 4.
So, i guess that only solution is to use extender. I’ll try with PCF8574 and see.

UPDATE:
now i managed to run first keypad add-on, too. However, there are some interesting “hacks” involved:

  • It DOES MATTER which gpio pins are input and/or output. Pins which are required to be at GND or +3.3V at bootup must be outputs, or keypad doesn’t work. So, my working pinout is:

byte colPins[n_cols] = {15, 0, 2}; //outputs
byte rowPins[n_rows] = {10, 14, 12, 13}; //inputs

  • pins are VERY sensitive: i have a keypad with rubber contacts (most of them have rubbers) and pressed resistance is around 1kohm, which is NOT enough for keypad to trigger. It can happen, but mostly it doesn’t. So i’ve had to dig out a keypad with mechanical switches in order to work flawlessly. This is one of the reasons i’d rather use I/O expander.

So, does anyone have an idea how to define them in above mentioned *.h file …?

Try a esp32.

Yeah, that’s a solution, true. I’m still waiting for a couple of them to arrive from China, though…
Another solution would be ESP8285, which has built-in flash, so that D0-D2 and CMD pins are free. (Yep, someone didn’t made a homework before ordering esp201…)
UPDATE: i did my homework this time: above claim is only partly true. Some pins ARE available inESP8285, but not all of them. So, gain is minimal…

I didn’t get any workable version with I/O yet, however. I did play a bit, helping with arduino library, but nothing workable came out. But, since keypad now works and i have I2C pins free it’s a usable solution. For keypad i guess i’ll just either made it myself with classic micro switches, or i might made some kind of a buffer between keypad and esp201.

Last couple of days I am testing joined PN532 tag reader, 4x4 matrix keypad, smart leds an piezzo buzzer hooked on esp32 powered by esphome. ESP32 also does presence detection via passive scanning BLE. So far, it works very well. Now I need to create case and mount everything in, but proof of concept is here. If you would like i can post all my code. Below is comment section where is described what is used.

I.S. esphome input and presence detection device
intended for use with HA alarm panel

NFC tag reader & writter (Based on Tag Reader for Home Assistant, https://github.com/adonno/tagreader, thanks to Andrea Donno)

Keypad, 4x4 matrix with both line and character input (based on ESPhome Keypad, https://github.com/Syralist/esphomekeypad, thanks to Thomas Helmke)

Bluetooth device presence detector using ESP32 bluetooth, passive scan

Exposed entities:
  Tagreader-Keypad sensors:
    - switch.${friendly_name}_buzzer_enabled
    - light.${friendly_name}_led_p1
    - light.${friendly_name}_led_p2
    - switch.${friendly_name}_led_enabled
    - binary_sensor.${friendly_name}_status
    - sensor.${friendly_name}_keypad_charsensor
    - sensor.${friendly_name}_keypad_textsensor
    - sensor.${friendly_name}_esphome_version
    - switch.${friendly_name}_restart
    - sensor.${friendly_name}_connected_bssid
    - sensor.${friendly_name}_connected_ssid
    - sensor.${friendly_name}_ip
    - sensor.${friendly_name}_mac_wifi_address

  BLE presence
    - binary_sensor.itag_blue
    - binary_sensor.itag_red
    - binary_sensor.itag_black

Hardware:
  Board:
    esp32doit devkit v1, ESP32 240MHz, 320KB RAM, 4MB Flash (EBay)
  PN532 Tag R/W:
    (EBay, 1set PN532 NFC RFID Wireless Module V3 User Breakout For Arduino For Android, https://www.ebay.com/itm/1set-PN532-NFC-RFID-Wireless-Module-V3-User-Breakout-For-Arduino-For-Android/183458101571?hash=item2ab6f47943:g:lsEAAOSwPU9bXDxM)
  Keypad:
    Matrix 4x4 (EBay, Switch Keypad Array Module Keys Button Membrane Switch DIY Kit For New, https://www.ebay.com/itm/Switch-Keypad-Array-Module-Keys-Button-Membrane-Switch-DIY-Kit-For-New/264963446275)
  LED PIXEL WS2801:
    (LED PIXEL S WS2801 KOCKASTI IP68, https://e-radionica.com/hr/led-pixel-s-ws2801-kockasti-ip68.html)

  BLE Tag:
    (EBay, Smart GPS Tracker Wireless Bluetooth Anti-Lost Alarm Finder Pet Locator Key W9J7, https://www.ebay.com/itm/Smart-GPS-Tracker-Wireless-Bluetooth-Anti-Lost-Alarm-Finder-Pet-Locator-Key-W9J7/233666540928)

Sure, it would be very helpfull if you post whole code. I never worked with ESP32 yet, let alone with BT. So any example is very usefull.

Well, there is a code:

Main tagreader_keypad.yaml:

# I.S. esphome input and presence detection device
# intended for use with HA alarm panel
#
# NFC tag reader & writter (Based on Tag Reader for Home Assistant, https://github.com/adonno/tagreader, thanks to Andrea Donno)
#
# Keypad, 4x4 matrix with both line and character input (based on ESPhome Keypad, https://github.com/Syralist/esphomekeypad, thanks to Thomas Helmke)
#
# Bluetooth device presence detector using ESP32 bluetooth, passive scan
#
# Exposed entities:
#   Tagreader-Keypad sensors:
#     - switch.${friendly_name}_buzzer_enabled
#     - light.${friendly_name}_led_p1
#     - light.${friendly_name}_led_p2
#     - switch.${friendly_name}_led_enabled
#     - binary_sensor.${friendly_name}_status
#     - sensor.${friendly_name}_keypad_charsensor
#     - sensor.${friendly_name}_keypad_textsensor
#     - sensor.${friendly_name}_esphome_version
#     - switch.${friendly_name}_restart
#     - sensor.${friendly_name}_connected_bssid
#     - sensor.${friendly_name}_connected_ssid
#     - sensor.${friendly_name}_ip
#     - sensor.${friendly_name}_mac_wifi_address
#
#   BLE presence
#     - binary_sensor.itag_blue
#     - binary_sensor.itag_red
#     - binary_sensor.itag_black
#
# Hardware:
#   Board:
#     esp32doit devkit v1, ESP32 240MHz, 320KB RAM, 4MB Flash (EBay)
#   PN532 Tag R/W:
#     (EBay, 1set PN532 NFC RFID Wireless Module V3 User Breakout For Arduino For Android, https://www.ebay.com/itm/1set-PN532-NFC-RFID-Wireless-Module-V3-User-Breakout-For-Arduino-For-Android/183458101571?hash=item2ab6f47943:g:lsEAAOSwPU9bXDxM)
#   Keypad:
#     Matrix 4x4 (EBay, Switch Keypad Array Module Keys Button Membrane Switch DIY Kit For New, https://www.ebay.com/itm/Switch-Keypad-Array-Module-Keys-Button-Membrane-Switch-DIY-Kit-For-New/264963446275)
#   LED PIXEL WS2801:
#     (LED PIXEL S WS2801 KOCKASTI IP68, https://e-radionica.com/hr/led-pixel-s-ws2801-kockasti-ip68.html)
#   Buzzer:
#     Not really active buzzer, this module don't have oscilator, just transistor, so it can be driven with very low current
#     (EBay, https://www.ebay.com/itm/5Pcs-Active-Buzzer-Module-3-3-5V-Low-Level-Trigger-Buzzer-3-Pin-Control-Board/372767092644?hash=item56caa66fa4:g:IiYAAOSwmUNdeQ9P)
#
#   BLE Tag:
#     (EBay, Smart GPS Tracker Wireless Bluetooth Anti-Lost Alarm Finder Pet Locator Key W9J7, https://www.ebay.com/itm/Smart-GPS-Tracker-Wireless-Bluetooth-Anti-Lost-Alarm-Finder-Pet-Locator-Key-W9J7/233666540928)
#
# Pin Map
#
# Keypad C1 <---> GPIO32
# Keypad C2 <---> GPIO33
# Keypad C3 <---> GPIO25
# Keypad C4 <---> GPIO26
# Keypad R1 <---> GPIO23
# Keypad R2 <---> GPIO18
# Keypad R3 <---> GPIO19
# Keypad R4 <---> GPIO05
#
# PN532 SDA <---> GPIO21 (SDA)
# PN532 SCL <---> GPIO22 (SCL)
#
# WS2801 DIN <--> GPIO04
# WS2801 CLIN <-> GPIO15
#
# Buzzer <------> GPIO27
#
# Keypad:
#         C1     C2     C3     C4
#   +--------------------------------+
#   |                                |
# R1|   | 1 |  | 2 |  | 3 |  | A |   |
#   |                                |
# R2|   | 4 |  | 5 |  | 6 |  | B |   |
#   |                                |
# R3|   | 7 |  | 8 |  | 9 |  | C |   |
#   |                                |
# R4|   | * |  | 0 |  | # |  | D |   |
#   |                                |
#   +--|--|--|--|--|--|--|--|--|--|--+
#      N  C  C  C  C  R  R  R  R  N
#      C  1  2  3  4  1  2  3  4  c
#
# Log:
#   2021-04-10
#     Instead of fixed timeout for ble presence defined in substitutions (ble_presence_timeout: 2 min),
#     added possibility to define this delay in HASS via input_number.ble_presence_timeout_value and sensor.ble_presence_timeout_int
#     and internal esphome sensor "BLE presence timeout"
#

wifi:
  networks:
    - ssid:  "IShome07"
      password: !secret wifi_password
    - ssid:  "IShome04"
      password: !secret wifi_password
    - ssid:  "IShome05"
      password: !secret wifi_password
    - ssid:  "IShome06"
      password: !secret wifi_password
  domain: !secret domain

  ap:
    ssid: ${devicename}
    password: !secret ap_password

# Enable the captive portal for inital WiFi setup
captive_portal:

substitutions:
  devicename: tagreader
  friendly_name: TagReader
  #ble_presence_timeout: 2 min

esphome:
  name: $devicename
  platform: ESP32
  board: esp32doit-devkit-v1
  # Keypadtext begin
  includes:
    - keypad_sensor_textsensor.h
  libraries:
    - "Keypad"
  # Keypadtext end

  on_boot:
    priority: -10
    then:
    - rtttl.play: "booted:d=64,o=7,b=120:c,p,p,c"
    - wait_until:
        api.connected:
    - binary_sensor.template.publish:
        id: itag_red
        state: OFF
    - binary_sensor.template.publish:
        id: itag_blue
        state: OFF
    - binary_sensor.template.publish:
        id: itag_black
        state: OFF
    - logger.log: API is connected!
    - rtttl.play: "startup:d=32,o=5,b=120:c,d,e,f,g,a,h"
    - light.turn_on:
        id: group_led
        #id: led_p1
        brightness: 100%
        red: 0%
        green: 0%
        blue: 100%
        flash_length: 500ms

  on_shutdown:
    then:
      - rtttl.play: "shutdown:d=32,o=5,b=120:h,a,g,f,e,d,c"

# Define switches to control LED and buzzer from HA
switch:
  - platform: template
    name: "${friendly_name} Buzzer Enabled"
    id: buzzer_enabled
    icon: mdi:volume-high
    optimistic: true
    restore_state: true
  - platform: template
    name: "${friendly_name} LED enabled"
    id: led_enabled
    icon: mdi:alarm-light-outline
    optimistic: true
    restore_state: true
  # Restart switch
  - platform: restart
    name: "${friendly_name} Restart"

# Logging
logger:
  #level: VERY_VERBOSE
  # level: VERBOSE
  #
  level: INFO
  baud_rate: 115200

# Enable Home Assistant API
api:
  password: !secret api_password
  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: string
    then:
    - rtttl.play: !lambda 'return song;'
    
  - service: play_auld_lang_syne
    then:
    - rtttl.play: "AuldLangSyne:d=4,o=5,b=100:4g,4c6,8c6,4c6,4e6,4d6,8c6,4d6,8e6,8d6,4c6,8c6,4e6,4g6,2a6,4a6,4g6,8e6,4e6,4c6,4d6,8c6,4d6,8e6,8d6,4c6,8a,4a,4g,2c6"

  - service: write_tag_random
    then:
    - lambda: |-
        static const char alphanum[] = "0123456789abcdef";
        std::string uri = "https://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 = "https://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();'

# Enable OTA upgrade
ota:
  password: !secret ota_password

i2c:
  sda: 21
  scl: 22
  scan: False
  frequency: 400kHz

pn532_i2c:
  id: pn532_board
  update_interval: 1s
  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("https://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: led_p2
            brightness: 100%
            red: 0%
            green: 100%
            blue: 0%
            flash_length: 500ms

# Define the buzzer output
output:
- platform: ledc
  pin: GPIO27
  id: buzzer

# Define buzzer as output for RTTTL
rtttl:
  output: buzzer

# Define status LED
status_led:
  pin:
    number: GPIO2
    inverted: True

# Configure RGB LEDs and partitions
light:
- platform: fastled_spi
  chipset: WS2801
  data_pin: GPIO4
  clock_pin: GPIO15
  default_transition_length: 10ms
  num_leds: 2
  rgb_order: RGB
  id: group_led
  name: "${friendly_name} LED base"
  restore_mode: ALWAYS_OFF
  internal: true

- platform: partition
  name: "${friendly_name} LED P1"
  id: "led_p1"
  segments:
    - id: group_led
      from: 0
      to: 0
  effects: !include light_effects.yaml

- platform: partition
  name: "${friendly_name} LED P2"
  id: "led_p2"
  segments:
    - id: group_led
      from: 1
      to: 1
  effects: !include light_effects.yaml
# RGB LED end

text_sensor:
  - platform: version
    name: "${friendly_name} ESPHome Version"

  - platform: custom
    lambda: |-
      auto keytext_sensor = new KeypadTextSensor();
      App.register_component(keytext_sensor);
      return {keytext_sensor->phrase_sensor, keytext_sensor->char_sensor};

    text_sensors:
      # Line text, '#' is enter and send input to HA, '*' is clear, means clear all input, send empty string to HA
      - name: "${friendly_name} Keypad TextSensor"
        id: "keypad_textsensor"
      # Pressed character as number, instantly sent to HA, valid for 500ms max.
      # Characters are 0,1,2,3,4,5,6,7,8,9 for numerics
      # 'A'=17, 'B'=18, 'C'=19, 'D'=20, '*'=-6, '#'=-13
      - name: "${friendly_name} Keypad CharSensor"
        id: "keypad_charsensor"
        on_value:
          - if:
              condition:
                lambda: 'return id(keypad_charsensor).state == "-13";'
              then:
                - if:
                    condition:
                      switch.is_on: buzzer_enabled
                    then:
                      - rtttl.play: "enter_beep:d=64,o=4,b=120:c,e,e"
                - if:
                    condition:
                      switch.is_on: led_enabled
                    then:
                      - light.turn_on:
                          id: led_p2
                          brightness: 50%
                          red: 0%
                          green: 100%
                          blue: 0%
                          flash_length: 250ms
          - if:
              condition:
                lambda: 'return id(keypad_charsensor).state == "-6";'
              then:
                - if:
                    condition:
                      switch.is_on: buzzer_enabled
                    then:
                      - rtttl.play: "clear_beep:d=32,o=4,b=120:e,c,c"
                - if:
                    condition:
                      switch.is_on: led_enabled
                    then:
                      - light.turn_on:
                          id: led_p2
                          brightness: 50%
                          red: 100%
                          green: 0%
                          blue: 100%
                          flash_length: 250ms
          - if:
              condition:
                and:
                  - lambda: 'return id(keypad_charsensor).state != "-6";'
                  - lambda: 'return id(keypad_charsensor).state != "-13";'
                  - lambda: 'return id(keypad_charsensor).state != "";'
              then:
                - if:
                    condition:
                      switch.is_on: buzzer_enabled
                    then:
                      - rtttl.play: "key_beep:d=32,o=7,b=120:g"
  - platform: wifi_info
    ip_address:
      name: "${friendly_name} IP"
    ssid:
      name: "${friendly_name} Connected SSID"
    bssid:
      name: "${friendly_name} Connected BSSID"
    mac_address:
      name: "${friendly_name} Mac Wifi Address"

# To replace ${ble_presence_timeout} with from home assistant adjustable value. See log.
sensor:
  - platform: homeassistant
    name: "BLE presence timeout"
    entity_id: sensor.ble_presence_timeout_int
    id: ble_presence_timeout_int
    internal: true
# To replace ${ble_presence_timeout} end

script:
  - id: itag_red_timer
    mode: restart
    then:
      - binary_sensor.template.publish:
          id: itag_red
          state: ON
      #- delay: ${ble_presence_timeout} # Replaced with from home assistant adjustable value. See log.
      - delay: !lambda 'return id(ble_presence_timeout_int).state * 1000;'
      - binary_sensor.template.publish:
          id: itag_red
          state: OFF

  - id: itag_blue_timer
    mode: restart
    then:
      - binary_sensor.template.publish:
          id: itag_blue
          state: ON
      #- delay: ${ble_presence_timeout} # Replaced with from home assistant adjustable value. See log.
      - delay: !lambda 'return id(ble_presence_timeout_int).state * 1000;'
      - binary_sensor.template.publish:
          id: itag_blue
          state: OFF

  - id: itag_black_timer
    mode: restart
    then:
      - binary_sensor.template.publish:
          id: itag_black
          state: ON
      #- delay: ${ble_presence_timeout} # Replaced with from home assistant adjustable value. See log.
      - delay: !lambda 'return id(ble_presence_timeout_int).state * 1000;'
      - binary_sensor.template.publish:
          id: itag_black
          state: OFF

esp32_ble_tracker:
  scan_parameters:
    active: false
    interval: 300ms
    window: 200ms
    duration: 5s
  on_ble_advertise:
    - mac_address: FF:FF:C0:05:D6:81
      then:
        - script.execute: itag_red_timer
    - mac_address: FF:FF:50:07:75:44
      then:
        - script.execute: itag_blue_timer
    - mac_address: FF:FF:BB:02:44:0C
      then:
        - script.execute: itag_black_timer

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

  - platform: template
    name: "iTag red"
    id: "itag_red"

  - platform: template
    name: "iTag blue"
    id: "itag_blue"

  - platform: template
    name: "iTag black"
    id: "itag_black"

Arduino code keypad_sensor_textsensor.h:

#include "esphome.h"
#include "Keypad.h"

class KeypadTextSensor : public Component {

    public:
    
    static const byte n_rows = 4;
    static const byte n_cols = 4;

    bool keyPublished = false;

    static const unsigned int resetTimeB = 500;
    unsigned int lastPublish = 0;
    
    char keys[n_rows][n_cols] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    
    byte colPins[n_cols] = {32, 33, 25, 26};
    byte rowPins[n_rows] = {23, 18, 19, 5};
    
    Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, n_rows, n_cols);

    std::string keysequenz;

    static const unsigned int resetTimeA = 300;
    unsigned int resetCounter = 0;
    bool keyPressed = false;
    TextSensor *phrase_sensor = new TextSensor();
    TextSensor *char_sensor = new TextSensor();
  
    
    void get_char(char ch) {
        char myKey = ch;
        if (myKey != NO_KEY){
            if (myKey == '#'){
                phrase_sensor->publish_state(keysequenz);
                keysequenz.clear();
                resetCounter = 0;
                keyPressed = false;
            }
            else if (myKey == '*'){
                keysequenz.clear();
                phrase_sensor->publish_state(keysequenz);
                resetCounter = 0;
                keyPressed = false;
            }
            else {
                keysequenz.push_back(myKey);
                keyPressed = true;
            }
        }
        if (keyPressed){
            resetCounter++;
        }
        if (resetCounter >= resetTimeA){
            keysequenz.clear();
            phrase_sensor->publish_state(keysequenz);
            resetCounter = 0;
            keyPressed = false;
        }
    }
    
    void loop() override {
    // This will be called by App.loop()
      
        char myKey = myKeypad.getKey();
        //myKey = NO_KEY;
        if (myKey != NO_KEY){
            int key = myKey - 48;
            char_sensor->publish_state(to_string(key));
            keyPublished = true;
            lastPublish = millis();
            get_char(myKey);
        }
        else{
            if (keyPublished && (millis() - lastPublish) >= resetTimeB){
                char_sensor->publish_state("");
                keyPublished = false;
            }
        }
    
    }

};

light_effects.yaml:

#   effects:
      - strobe:
          name: strobe_alarm_away_armed
          colors:
            - state: True
              brightness: 50%
              red: 100%
              green: 0%
              blue: 0%
              duration: 500ms
            - state: False
              duration: 500ms
      - strobe:
          name: strobe_alarm_home_armed
          colors:
            - state: True
              brightness: 50%
              red: 0%
              green: 0%
              blue: 100%
              duration: 500ms
            - state: False
              duration: 500ms
      - strobe:
          name: strobe_alarm_tripping
          colors:
            - state: True
              brightness: 50%
              red: 100%
              green: 100%
              blue: 0%
              duration: 250ms
            - state: True
              brightness: 50%
              red: 100%
              green: 50%
              blue: 100%
              duration: 250ms
      - strobe:
          name: strobe_alarm_tripped
          colors:
            - state: True
              brightness: 50%
              red: 100%
              green: 0%
              blue: 0%
              duration: 250ms
            - state: True
              brightness: 50%
              red: 0%
              green: 0%
              blue: 100%
              duration: 250ms

As I mention in comment, large parts of code are not mine, however I ‘glued’ it together to suit my needs.
Enjoy & best regards!

1 Like

Thanks!
As i see above there’s still quite a lot to learn and understand…

If anyone is interested, i just finished a project with a 3x4 keypad, SX1509 and NodeMCU. Detailed on r/HomeAssistant here: https://www.reddit.com/r/homeassistant/comments/qim9w7/finally_completed_my_programmable_garage_keypad/?

1 Like

Thanks for the new update
Could i still use the same nodemcu board for the keypad and the fingerprint reader?

These days i’m trying pn532 and rc522 rfid readers. Is it normal that pn532 is waaay slower than rc522? I mean - rc522 recognizes instantly, while pn532 takes around 1 second. Is it because pn532 also reads additional data while rc522 doesn’t? Is it possible to turn off additional data reading (if this would cause faster response)?