Browse docs
Frontelio Access · Hardware

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.

BuildPartsCostBest for
Raspberry Pi 4Pi 4 (2GB) + PN532 + 5V relay + LEDs + buzzer + 32GB SD~$75Headend door. Full Linux, easy SSH, ample CPU.
Raspberry Pi Zero 2WPi Zero 2W + PN532 + 5V relay + LEDs + 16GB SD~$45Tight ceiling spaces. Same software stack as Pi 4.
ESP32 + PN532ESP32 dev board + PN532 + 5V relay + LEDs~$25Bulk 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

bash
sudo raspi-config
  • Interface Options → Serial Port
  • "login shell over serial?" → No
  • "serial port hardware enabled?" → Yes

Reboot.

Step 3 — Install the bridge

bash
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.sh

The installer:

  • Creates /opt/frontelio-bridge with a venv.
  • pip-installs requirements.txt.
  • Installs the systemd unit.
  • Copies config.example.toml to /etc/frontelio-bridge/config.toml if no config exists yet.

Step 4 — Configure

bash
sudo nano /etc/frontelio-bridge/config.toml

Edit at minimum the [frontelio] section:

toml
[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

bash
sudo systemctl start frontelio-bridge
sudo journalctl -u frontelio-bridge -f

You should see:

journalctl
[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=0

Local health-check endpoint as a smoke test:

bash
curl http://localhost:8080/health

Step 6 — Bind in the admin UI

  1. Sign in to your tenant.
  2. Go to /admin/access → Readers. The bridge should appear within ~5 min of starting, marked online.
  3. Go to /admin/access → Zones. Create (or edit) a Zone and set readers to include the reader_id you used above.
  4. Make sure at least one user has an active Grant for that Zone.
  5. 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, sometimes HSU). Verify with dmesg | grep tty that /dev/ttyAMA0 exists.
  • No heartbeat in admin UI — usually a wrong api_key (returns 401, visible in journalctl) or the Pi can't reach api.frontelio.com (try curl https://api.frontelio.com/api/v1/healthz from 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_id in config.tomldoesn't match the value in the Zone's reader list. Spelling matters; copy-paste, don't retype.