# ESP32 PN532 Door Reader

Firmware scaffold for the L484 NFC door reader.

## Role

The ESP32 reads the NFC credential from the PN532 and asks the local L484 backend whether access is allowed.

For the Kwikset Home Connect 918 path, the ESP32 does **not** unlock the door directly. The backend triggers Home Assistant/Z-Wave JS, which sends the unlock command through the Zooz ZST39 LR to the Kwikset lock.

## Setup

1. Install PlatformIO.
2. Copy `include/l484_door_config.example.h` to `include/l484_door_config.h`.
3. Fill in:
   - Wi-Fi SSID/password.
   - L484 backend access URL.
   - `ACCESS_CONTROLLER_TOKEN`.
   - `doorId`.
   - PN532 pins and card mode.
4. Build/upload:

```bash
pio run -t upload
pio device monitor
```

## Wiring

Photo overlay using the supplied board pictures:

![ESP32 to PN532 photo wiring overlay](../../docs/assets/esp32-pn532-photo-overlay.svg)

Clean schematic:

![ESP32 to PN532 wiring diagram](../../docs/assets/esp32-pn532-wiring.svg)

Default ESP32 dev board wiring:

- PN532 `VCC` -> ESP32 `3V3`
- PN532 `GND` -> ESP32 `GND`
- PN532 `SDA` -> ESP32 `GPIO21`
- PN532 `SCL` -> ESP32 `GPIO22`
- PN532 `IRQ` -> ESP32 `GPIO4`
- PN532 `RSTO/RST` -> ESP32 `GPIO5`

Set the PN532 board switches to I2C mode.

## Card Modes

`CARD_MODE_UID` submits the card UID as hex. Use this for bench testing only.

`CARD_MODE_MIFARE_CLASSIC_BLOCK` reads a MIFARE Classic block and submits the text secret stored there. This is the preferred first production direction because UID-only cards are cloneable.

## Fail-Closed Behavior

The firmware denies access if:

- Wi-Fi is unavailable.
- PN532 read fails.
- Backend times out.
- Backend returns non-2xx.
- Backend response does not include `"allow":true`.
