PHP code example of olorunda / laravel-aiface-websocket
1. Go to this page and download the library: Download olorunda/laravel-aiface-websocket library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
olorunda / laravel-aiface-websocket example snippets
use AiFace\WebSocket\Facades\AiFace;
use AiFace\WebSocket\Core\Protocol;
// Check if device is connected online
if (AiFace::isOnline('LF00000001')) {
echo "Device is online!";
}
// 1. Remote Unlock Door
$response = AiFace::device('LF00000001')->openDoor(doorNum: 1);
// 2. Synchronize Device Clock with Server Time
$response = AiFace::device('LF00000001')->syncTime();
// 3. Reboot Device Hardware
$response = AiFace::device('LF00000001')->reboot();
// 4. Enroll User with Face Photo (base64 JPG)
$response = AiFace::device('LF00000001')->setUserFacePhoto(
enrollId: 101,
name: 'Sarah Connor',
base64Jpg: base64_encode(file_get_contents('/path/to/face.jpg')),
admin: 0
);
// 5. Enroll User with RFID Card Number
$response = AiFace::device('LF00000001')->setUserCard(
enrollId: 102,
name: 'John Doe',
cardNumber: '9876543210'
);
// 6. Enroll User with PIN / Password
$response = AiFace::device('LF00000001')->setUserPassword(
enrollId: 103,
name: 'Admin User',
pwd: 123456,
admin: 1 // Device administrator
);
// 7. Pull Unread Attendance Records
$logs = AiFace::device('LF00000001')->getNewLog();
// 8. Trigger Device-Side Enrollment Wizard on hardware screen
AiFace::device('LF00000001')->addUser(
enrollId: 105,
backupNum: Protocol::BACKUP_FP_0 // Fingerprint slot 0
);
namespace App\Http\Controllers;
use AiFace\WebSocket\Facades\AiFace;
use AiFace\WebSocket\Core\Protocol;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class BiometricEmployeeController extends Controller
{
protected string $deviceSn = 'LF00000001';
/**
* Step 1: Enroll an employee onto the biometric terminal
*/
public function enroll(Request $request, int $userId): JsonResponse
{
$employee = User::findOrFail($userId);
// 1. Verify the biometric hardware terminal is connected online
if (!AiFace::isOnline($this->deviceSn)) {
return response()->json([
'success' => false,
'message' => "Terminal [{$this->deviceSn}] is currently offline.",
], 503);
}
// 2. Check remaining device memory/capacity before adding
$cap = AiFace::device($this->deviceSn)->getDevCap();
if (($cap['useduser'] ?? 0) >= ($cap['usersize'] ?? 10000)) {
return response()->json([
'success' => false,
'message' => 'Terminal user capacity is full.',
], 422);
}
// 3. Enroll employee with card and/or PIN password
// (backupnum: 10 = password, 11 = card, 50 = face photo)
$enrollResult = AiFace::device($this->deviceSn)->setUserInfo(
enrollId: $employee->id,
name: $employee->name,
backupNum: Protocol::BACKUP_PASSWORD,
record: $request->input('pin', '123456'), // User PIN
admin: $employee->is_admin ? 1 : 0, // 1 = Terminal Administrator
enable: 1, // 1 = Active, 0 = Suspended
extra: [
'card' => $request->input('card_number', '99887766'),
'aliasid' => 'EMP-' . $employee->id,
]
);
// 4. (Optional) Enroll face photo if uploaded
if ($request->hasFile('face_photo')) {
$base64Image = base64_encode(file_get_contents($request->file('face_photo')->getRealPath()));
AiFace::device($this->deviceSn)->setUserFacePhoto(
enrollId: $employee->id,
name: $employee->name,
base64Jpg: $base64Image
);
}
// 5. (Optional) Prompt the device screen to open enrollment wizard for fingerprint
if ($request->boolean('scan_fingerprint')) {
AiFace::device($this->deviceSn)->addUser(
enrollId: $employee->id,
backupNum: Protocol::BACKUP_FP_0 // Fingerprint slot 0
);
}
return response()->json([
'success' => true,
'message' => "Employee #{$employee->id} ({$employee->name}) enrolled successfully.",
'terminal_response' => $enrollResult,
]);
}
/**
* Step 2: Offboard / Delete an employee from the biometric terminal
*/
public function offboard(int $userId): JsonResponse
{
$employee = User::findOrFail($userId);
if (!AiFace::isOnline($this->deviceSn)) {
return response()->json([
'success' => false,
'message' => "Terminal [{$this->deviceSn}] is offline. Reconnect terminal to delete.",
], 503);
}
// Delete user and all associated biometric credentials (face, fingerprints, card, PIN)
$deleteResult = AiFace::device($this->deviceSn)->deleteUser(
enrollId: $employee->id
);
return response()->json([
'success' => true,
'message' => "Employee #{$employee->id} deleted from terminal.",
'terminal_response' => $deleteResult,
]);
}
/**
* Step 3: Revoke only a specific credential (e.g. lost RFID card) without deleting user
*/
public function revokeCard(int $userId): JsonResponse
{
// Deleting with backupNum = 11 removes only the RFID card credential
$result = AiFace::device($this->deviceSn)->deleteUser(
enrollId: $userId,
backupNum: Protocol::BACKUP_CARD
);
return response()->json([
'success' => true,
'message' => "RFID card revoked for user #{$userId}.",
'terminal_response' => $result,
]);
}
/**
* Step 4: Delayed / Scheduled Deletion (Auto-Expire Access)
* Useful for hotel guests, temporary visitors, contract workers, or scheduled offboarding.
*/
public function scheduleOffboarding(int $userId): JsonResponse
{
// Option A: Pass delay in seconds (e.g., 3600 = 1 hour)
$result = AiFace::device($this->deviceSn)->deleteUser(
enrollId: $userId,
delay: 3600
);
// Option B: Pass a Carbon / DateTime instance
// $result = AiFace::device($this->deviceSn)->delayedDeleteUser(
// enrollId: $userId,
// delay: now()->addHours(8)
// );
return response()->json([
'success' => true,
'message' => "User #{$userId} scheduled for automatic removal when time elapses.",
'task' => $result,
]);
}
/**
* Step 5: Cancel a scheduled deletion before it elapses
*/
public function cancelScheduledOffboarding(int $userId): JsonResponse
{
$result = AiFace::device($this->deviceSn)->cancelDelayedDelete($userId);
return response()->json([
'success' => true,
'result' => $result,
]);
}
}
namespace App\Listeners;
use AiFace\WebSocket\Events\UserClockedIn;
use AiFace\WebSocket\Events\UserClockedOut;
use App\Models\Timesheet;
use Illuminate\Support\Facades\Log;
class HandleBiometricAttendance
{
/**
* Handle Clock-In (Check-In) Events
*/
public function handleClockIn(UserClockedIn $event): void
{
Log::info("Employee #{$event->enrollId} ({$event->name}) clocked IN on terminal {$event->sn} at {$event->time} via {$event->modeDesc}");
// Record attendance in your database
Timesheet::create([
'user_id' => $event->enrollId,
'employee_name' => $event->name,
'device_sn' => $event->sn,
'action' => 'clock_in',
'punch_time' => $event->time,
'verification' => $event->modeDesc, // e.g. "Face Recognition", "Fingerprint", "Card", "Password"
'snapshot_base64' => $event->image, // Captured snapshot if terminal camera is configured
]);
// Trigger notifications, Slack alerts, or dispatch payroll sync jobs
}
/**
* Handle Clock-Out (Check-Out) Events
*/
public function handleClockOut(UserClockedOut $event): void
{
Log::info("Employee #{$event->enrollId} ({$event->name}) clocked OUT on terminal {$event->sn} at {$event->time}");
Timesheet::create([
'user_id' => $event->enrollId,
'employee_name' => $event->name,
'device_sn' => $event->sn,
'action' => 'clock_out',
'punch_time' => $event->time,
'verification' => $event->modeDesc,
]);
}
}
namespace App\Providers;
use AiFace\WebSocket\Events\UserClockedIn;
use AiFace\WebSocket\Events\UserClockedOut;
use App\Listeners\HandleBiometricAttendance;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Event::listen(UserClockedIn::class, [HandleBiometricAttendance::class, 'handleClockIn']);
Event::listen(UserClockedOut::class, [HandleBiometricAttendance::class, 'handleClockOut']);
}
}
use AiFace\WebSocket\Events\UserClockedIn;
use AiFace\WebSocket\Events\UserClockedOut;
use AiFace\WebSocket\Events\UserDeleteScheduled;
use AiFace\WebSocket\Events\UserDeleted;
use AiFace\WebSocket\Events\AttendanceLogReceived;
use AiFace\WebSocket\Events\DeviceRegistered;
use Illuminate\Support\Facades\Event;
// Triggered whenever a user clocks in (inout = 0)
Event::listen(UserClockedIn::class, function (UserClockedIn $event) {
logger()->info("User #{$event->enrollId} ({$event->name}) clocked IN on {$event->sn} at {$event->time} via {$event->modeDesc}");
// Example: send SMS, notify Slack, update attendance timesheet
});
// Triggered whenever a user clocks out (inout = 1)
Event::listen(UserClockedOut::class, function (UserClockedOut $event) {
logger()->info("User #{$event->enrollId} ({$event->name}) clocked OUT on {$event->sn} at {$event->time}");
});
// Triggered when a delayed deletion task is scheduled
Event::listen(UserDeleteScheduled::class, function (UserDeleteScheduled $event) {
logger()->info("User #{$event->enrollId} scheduled for deletion on {$event->sn} in {$event->delaySeconds}s (at " . date('Y-m-d H:i:s', $event->executeAt) . ")");
});
// Triggered when deletion is transmitted and effected on device
Event::listen(UserDeleted::class, function (UserDeleted $event) {
logger()->info("User #{$event->enrollId} deleted on {$event->sn}");
});
// Triggered when a device registers or completes handshake
Event::listen(DeviceRegistered::class, function (DeviceRegistered $event) {
logger()->info("AiFace device {$event->sn} registered from IP: {$event->ip}");
});
'webhooks' => [
'enabled' => true,
'url' => 'https://your-domain.com/webhooks/aiface',
'secret' => 'your-secret-key',
'events' => [
'attendance.clockin', // Individual user clock-in punch
'attendance.clockout', // Individual user clock-out punch
'attendance.logged', // Batch attendance log payload
'device.registered', // Device handshake completed
'device.connected', // New socket connected
'device.disconnected', // Device disconnected
'user.pushed', // On-device user enrollment report
'user.delete_scheduled', // User deletion task scheduled
'user.deleted', // User deletion effected on device
'pin.received', // Door access PIN entered
'qrcode.scanned', // Visitor/employee QR code scan
'gps.received', // Device GPS location
'intercom.call', // Video intercom doorbell ring
],
],