I have three garage doors I needed RFID access control for. All of them are already controlled by Home Assistant using ESP8266’s and ESPHome. So what I needed was a simple RFID reader that could send tag ID to Home Assistant for processing. Home Assistant will check if the tag is valid and if so, which door to open. The tag reader is relatively cheap one from Ali Express combined with an Wemos D1 mini running ESPHome, which is natively supported in Home Assistant.
I have two different kind of readers, one simple for my workshop door, and one more complex for the dual garage doors. The latter one features two wiegand readers as seen in the video, one for each door. In addition it has two physical buttons on the inside for controlling the doors from inside. Both of the readers feature a buzzer.
The code for the simple one is here:
esphome:
includes:
- wiegand_device.h
name: rfid-verksted
platform: ESP8266
board: d1_mini
wifi:
ssid: "your_ssid"
password: "your_pwd"
captive_portal:
logger:
api:
ota:
light:
- platform: status_led
name: "LED"
pin:
number: D4
#inverted: true
internal: true
sensor:
- platform: custom
lambda: |-
auto wiegand = new WiegandReader(D1, D2);
App.register_component(wiegand);
return {wiegand};
sensors:
name: "RFID Verksted"
on_value:
then:
- homeassistant.tag_scanned: !lambda |-
char buf[16];
sprintf(buf, "%.0f", x);
std::string s = buf;
std::string y = "Verksted: " + s;
return y;
switch:
- platform: gpio
id: "beep"
pin: D3
inverted: yes
internal: true
- platform: template
name: "Denied beep Verksted"
icon: "mdi:bell-alert"
id: long_beep
turn_on_action:
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- delay: 100ms
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- delay: 100ms
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- delay: 100ms
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- switch.turn_off: long_beep
- platform: template
name: "Granted beep Verksted"
icon: "mdi:bell-alert-outline"
id: two_beep
turn_on_action:
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- switch.turn_off: two_beep
Code for the more complex one is here:
esphome:
includes:
- wiegand_device.h
- wiegand_device2.h
name: rfid-garasje
platform: ESP8266
board: d1_mini
wifi:
ssid: "your_ssid"
password: "your_pwd"
captive_portal:
logger:
api:
ota:
light:
- platform: status_led
name: "LED"
pin:
number: D4
#inverted: true
internal: true
sensor:
- platform: custom
lambda: |-
auto wiegand = new WiegandReader(D1, D2);
App.register_component(wiegand);
return {wiegand};
sensors:
name: "RFID Garasje Høyre"
on_value:
then:
- homeassistant.tag_scanned: !lambda |-
char buf[16];
sprintf(buf, "%.0f", x);
std::string s = buf;
std::string y = "GarasjeH: " + s;
return y;
- platform: custom
lambda: |-
auto wiegand = new WiegandReader2(D7, D8);
App.register_component(wiegand);
return {wiegand};
sensors:
name: "RFID Garasje Venstre"
on_value:
then:
- homeassistant.tag_scanned: !lambda |-
char buf[16];
sprintf(buf, "%.0f", x);
std::string u = buf;
std::string t = "GarasjeV: " + u;
return t;
binary_sensor:
- platform: gpio
pin:
number: D6
inverted: true
mode:
input: true
pullup: true
name: RFID knapp høyre port
filters:
- delayed_on: 20ms
- delayed_off: 100ms
- platform: gpio
pin:
number: D5
inverted: true
mode:
input: true
pullup: true
name: RFID knapp venstre port
filters:
- delayed_on: 20ms
- delayed_off: 100ms
switch:
- platform: gpio
id: "beep"
pin: D3
inverted: yes
internal: true
- platform: template
name: "Denied beep Garasje"
icon: "mdi:bell-alert"
id: long_beep
turn_on_action:
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- delay: 100ms
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- delay: 100ms
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- delay: 100ms
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- switch.turn_off: long_beep
- platform: template
name: "Granted beep Garasje"
icon: "mdi:bell-alert-outline"
id: two_beep
turn_on_action:
- switch.turn_on: beep
- delay: 100ms
- switch.turn_off: beep
- switch.turn_off: two_beep
Wiring is easy, just read the code. As wiegand protocol is not natively supported in ESPHome, you also need to put the file “wiegand_device.h” in the esphome folder in Home Asssistant.
When everything is set up correctly, scanned tags are sent to Home Assistant as “tag_scanned” events, and will also show up in the native Home Assistant “Tags” section. The format tags are sent in is [reader_name]: [tag_id]. This can of course easily be changed in the code to e.g. just send the tag ID.
I use node red to listen to tag_scanned events, and when discovered, it splits the response in two, checks latter part (tag_id), if approved, checks first part (which reader), sends beeps to the reader buzzer, and then opens the door. If tag is invalid a rapid series of beeps is played in the reader buzzer.
Probably forgot a lot, if anyone is interrested in building something similar, I’d be happy to help.