Deploy a reader bridge.
The reference reader bridge turns a Raspberry Pi or ESP32 plus a $5 NFC module into a Frontelio Access reader. Six steps from a blank SD card to a working door, in under 30 minutes.
What the bridge is
A small Linux daemon (or microcontroller firmware on ESP32) that polls an NFC reader, reads the JWT credential the phone broadcasts via Host Card Emulation, POSTs it to /access/verify, and pulses a relay if the API responds GRANT. The bridge has no secrets of its own beyond a per-tenant API key — all the policy lives server-side, so revoking a grant takes effect on the next tap regardless of bridge state.
This is the open reference implementationwe ship for cafés deploying phone-tap access for the first time. It's intentionally one Python file (plus a thin hardware abstraction) so a non-Frontelio engineer can read it, audit it, and modify it for their site.
When you need a bridge
- Greenfield cafe / kitchen / store. No existing access readers, no incumbent system. Bridge is the cheapest path to a working door — $75 of parts per door for the recommended Pi 4 build.
- One-off side door.You have Kisi on the main entrance but need to control a back door that Kisi can't reach. Bridge plugs the gap.
- You're a pilot deployment for Frontelio Access and want to see the full picture end-to-end before committing to enterprise readers.
If you already own Kisi / Salto / Brivo / HID Origo readers, skip this page and go to Integrations instead.
Hardware shopping list
Three reference builds, depending on budget and operating environment. All three use the same PN532 NFC module — that part is universal.
| Build | Parts | Cost | Best for |
|---|---|---|---|
| Raspberry Pi 4 | Pi 4 (2GB) + PN532 + 5V relay + LEDs + buzzer + 32GB SD | ~$75 | Headend door. Full Linux, easy SSH, ample CPU. |
| Raspberry Pi Zero 2W | Pi Zero 2W + PN532 + 5V relay + LEDs + 16GB SD | ~$45 | Tight ceiling spaces. Same software stack as Pi 4. |
| ESP32 + PN532 | ESP32 dev board + PN532 + 5V relay + LEDs | ~$25 | Bulk rollouts where unit cost matters more than flexibility. |
Deploy in 6 steps
End-to-end checklist for a brand-new Raspberry Pi reader. ESP32 builds are similar but flash firmware instead of running a daemon — see bridge/esp32/README.md in the source repo.
Step 1 — Flash Raspberry Pi OS Lite
Use the official Raspberry Pi Imager. Pick:
- OS: Raspberry Pi OS Lite (64-bit) — Bookworm or newer.
- Use SSH: yes, with a password. Set a hostname like
frontelio-bridge-cafe1-door1. - WiFi (or Ethernet): configure either. WiFi is fine — worst-case bandwidth is measured in KB/min.
Boot the Pi and confirm you can SSH in: ssh pi@frontelio-bridge-cafe1-door1.
Step 2 — Enable UART, disable serial console
sudo raspi-config- Interface Options → Serial Port
- "login shell over serial?" → No
- "serial port hardware enabled?" → Yes
Reboot.
Step 3 — Install the bridge
sudo apt-get update -y
sudo apt-get install -y git
cd /opt
sudo git clone https://github.com/missan/frontline-control-os.git
cd frontline-control-os/bridge/rpi
sudo bash install.shThe installer:
- Creates
/opt/frontelio-bridgewith a venv. - pip-installs
requirements.txt. - Installs the systemd unit.
- Copies
config.example.tomlto/etc/frontelio-bridge/config.tomlif no config exists yet.
Step 4 — Configure
sudo nano /etc/frontelio-bridge/config.tomlEdit at minimum the [frontelio] section:
[frontelio]
api_base = "https://api.frontelio.com/api/v1"
api_key = "mk_REPLACE_WITH_THE_KEY_YOU_JUST_MINTED"
reader_id = "BRIDGE-cafe1-door1"
[hardware]
nfc_device = "pn532_uart"
nfc_path = "/dev/ttyAMA0"
relay_gpio = 17
relay_pulse_ms = 800
[behavior]
verify_timeout_seconds = 2.0
led_grant_gpio = 22
led_deny_gpio = 23
# buzzer_gpio = 27- api_key — paste the
mk_*key you minted from/admin/access → API keys. Each key is shown once on creation; copy it immediately. - reader_id — a unique name for this bridge. Convention:
BRIDGE-<outletCode>-<doorName>. You'll bind this to a Zone in step 6.
Step 5 — Start the service
sudo systemctl start frontelio-bridge
sudo journalctl -u frontelio-bridge -fYou should see:
[INFO] frontelio-bridge started reader_id=BRIDGE-cafe1-door1 ...
[INFO] PN532 UART reader initialised on /dev/ttyAMA0 ...
[INFO] heartbeat ok reader_id=BRIDGE-cafe1-door1 taps_today=0Local health-check endpoint as a smoke test:
curl http://localhost:8080/healthStep 6 — Bind in the admin UI
- Sign in to your tenant.
- Go to
/admin/access → Readers. The bridge should appear within ~5 min of starting, marked online. - Go to
/admin/access → Zones. Create (or edit) a Zone and setreadersto include thereader_idyou used above. - Make sure at least one user has an active Grant for that Zone.
- Open the user's mobile app, go to More → My Access, and tap the phone on the PN532. The relay should click within ~150 ms and you'll see a GRANT event in the bridge's journal and in the Audit log.
Troubleshooting
- "PN532 not found" — DIP switches on the breakout. Both should be in the UART position (sometimes labelled
SEL0 ON / SEL1 OFF, sometimesHSU). Verify withdmesg | grep ttythat/dev/ttyAMA0exists. - No heartbeat in admin UI — usually a wrong
api_key(returns 401, visible injournalctl) or the Pi can't reachapi.frontelio.com(trycurl https://api.frontelio.com/api/v1/healthzfrom the Pi). - GRANT in journal but no door click— wiring on the relay. Wire an LED across the relay's NO/COM pins as a test, you should see it light for ~800 ms on a tap.
- DENY with reason "Unknown reader" — the
reader_idinconfig.tomldoesn't match the value in the Zone's reader list. Spelling matters; copy-paste, don't retype.