Introduction
Physical access control is stuck in the past: either a guard watches CCTV feeds, or you install a costly cloud-based facial recognition service that streams video—and pays a per-camera subscription. Both approaches burn money and expose private data to the internet.
What if the detection happens on the device itself? The $10 ESP32-CAM module with an OV2640 sensor can run face detection at the edge using Espressif's ESP-WHO firmware. It publishes only the result—a person ID and confidence score—rather than a video stream. That's where the ASI Biont AI agent comes in. It subscribes to these events over MQTT, maps a recognized face to your CRM or 1C system, and triggers actions like opening a door or alerting a guard.
In this article, I'll show how to connect an ESP32-CAM/OV2640 face-detection node to ASI Biont, why MQTT is the right protocol for this edge AI use case, and how to set it up entirely through chat—with no dashboards or vendor lock-in.
The Device: ESP32-CAM with OV2640
The ESP32-CAM is a low-cost development board that combines an ESP32-WROVER module (240 MHz, 4 MB PSRAM) with an OV2640 camera and a microSD slot. It is one of the cheapest devices to run real-time face detection at the edge. Espressif's open-source ESP-WHO framework provides pre-trained face detection models and works well with this sensor. The board can detect multiple faces within a few meters, and it can output the bounding boxes and recognition results over UART, Wi-Fi, or MQTT.
For our access-control scenario, the ESP32-CAM runs a custom ESP-WHO firmware that, on a successful recognition, publishes a compact JSON event to a local MQTT broker. The payload contains only the essential fields: person ID, confidence, and timestamp. Network load drops from a continuous video stream (hundreds of kbps) to a few hundred bytes per event.
Why MQTT?
MQTT is the de facto standard for event-driven IoT communication. It is pub/sub, supports quality-of-service levels, and works over low-bandwidth Wi-Fi. The Python paho-mqtt library is stable and well-documented. Other protocols are also available in ASI Biont:
| Interface | Event push | Latency | Bandwidth | Best for |
|---|---|---|---|---|
| MQTT | Yes | 50-100 ms | Low | Event-driven sensors and cameras |
| Modbus/TCP | No (polled) | High | Medium | PLC registers, industrial I/O |
| HTTP API | No (polling) | High | High | Devices with webhooks |
| COM port (Hardware Bridge) | Yes (serial) | Low | Low | Legacy RS-232/485 devices |
For this device, MQTT is the obvious choice because face detection is inherently event-based.
Real-World Scenario: Smart Office Entrance
A company with 120 employees uses a physical access card system. Tailgating is a persistent issue: one employee enters, and two people follow. There is no real-time record of exactly who is inside. The security team manually reviews CCTV after a breach—slow and expensive.
After the integration, the entrance runs on edge AI and an agent:
- Edge detection: ESP32-CAM runs ESP-WHO, recognizes a face, and sends a JSON message to
cameras/entrance/face. - Biont subscribes: The AI-generated Python script (created in the chat from your description) subscribes to that topic, parses the JSON, and queries 1C via its HTTP API.
- Door control: If the person is an active employee, Biont sends an
openingcommand to a relay via Modbus/TCP (the relay triggers the turnstile). If unknown, Biont posts a Telegram alert to the security group.
This flow eliminates the need for a full-time guard at the entrance and gives a clean audit log in 1C. In a pilot installation, security costs dropped noticeably and the average time between face detection and door opening stayed under 200 ms.
MicroPython code on the ESP32-CAM
If you use the umqtt.simple library, publishing an event takes a few lines. This is a minimal example; in production, the person_id field would be supplied by your face-detection routine.
import network
import ujson
import time
from umqtt.simple import MQTTClient
WIFI_SSID = "office-net"
WIFI_PASS = "P@ssw0rd"
MQTT_BROKER = "192.168.1.50"
MQTT_TOPIC = b"cameras/entrance/face"
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASS)
while not wlan.isconnected():
time.sleep(0.2)
client = MQTTClient("esp32cam", MQTT_BROKER)
client.connect()
event = {
"event": "face_recognized",
"person_id": "emp-134",
"confidence": 0.98,
"camera": "entrance"
}
client.publish(MQTT_TOPIC, ujson.dumps(event).encode())
client.disconnect()
Python code generated by ASI Biont
The AI agent generates a Python subscriber that connects to the MQTT broker, waits for a face event (with a timeout), and executes the required business logic. The execute_python sandbox has a 30-second timeout, so this script is designed as a one-shot poller; for continuous operation you can deploy the same code on a Raspberry Pi.
import paho.mqtt.client as mqtt
import json
import time
import requests
BROKER = "192.168.1.50"
TOPIC = "cameras/entrance/face"
captured = {}
def on_message(client, userdata, msg):
captured["event"] = json.loads(msg.payload)
client.loop_stop()
client = mqtt.Client()
client.on_message = on_message
client.connect(BROKER, 1883, 60)
client.subscribe(TOPIC)
timeout = time.monotonic() + 5
while "event" not in captured and time.monotonic() < timeout:
client.loop(0.2)
client.disconnect()
if "event" not in captured:
print("No face event within 5 seconds")
else:
event = captured["event"]
person_id = event.get("person_id")
if person_id:
emp = requests.get(f"http://10.0.0.5:8010/employees/{person_id}", timeout=5).json()
requests.post("https://api.telegram.org/bot<TOKEN>/sendMessage",
data={"chat_id": emp["telegram"],
"text": f"Hello {emp['name']}, you are marked present."})
print(f"✅ {emp['name']} entered at {event['timestamp']}")
else:
requests.post("https://api.telegram.org/bot<TOKEN>/sendMessage",
data={"chat_id": "@office_security",
"text": f"⚠️ Unknown person at entrance!\
Comments