PHP code example of shaykhnazar / hikvision-isapi

1. Go to this page and download the library: Download shaykhnazar/hikvision-isapi 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/ */

    

shaykhnazar / hikvision-isapi example snippets


return [
    'default' => env('HIKVISION_DEFAULT_DEVICE', 'primary'),

    'devices' => [
        'primary' => [
            'ip' => env('HIKVISION_IP', '192.168.1.100'),
            'port' => env('HIKVISION_PORT', 80),
            'username' => env('HIKVISION_USERNAME', 'admin'),
            'password' => env('HIKVISION_PASSWORD'),
            'protocol' => env('HIKVISION_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_VERIFY_SSL', false),
        ],
    ],

    'format' => env('HIKVISION_FORMAT', 'json'),

    'logging' => [
        'enabled' => env('HIKVISION_LOGGING', true),
        'channel' => env('HIKVISION_LOG_CHANNEL', 'stack'),
    ],
];

use Shaykhnazar\HikvisionIsapi\Services\DeviceService;

$deviceService = app(DeviceService::class);

if ($deviceService->isOnline()) {
    $info = $deviceService->getInfo();
    echo "Device Model: " . $info['DeviceInfo']['model'];
}

use Shaykhnazar\HikvisionIsapi\Services\PersonService;
use Shaykhnazar\HikvisionIsapi\DTOs\Person;
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

$personService = app(PersonService::class);

$person = new Person(
    employeeNo: 'EMP001',
    name: 'John Doe',
    userType: UserType::NORMAL,
    validEnabled: true,
    beginTime: now()->toISOString(),
    endTime: now()->addYear()->toISOString(),
    doorRight: '1',
    rightPlan: [
        ['doorNo' => 1, 'planTemplateNo' => '1']
    ]
);

$response = $personService->add($person);

use Shaykhnazar\HikvisionIsapi\Services\FaceService;

$faceService = app(FaceService::class);

// Read image file
$imageData = file_get_contents('path/to/photo.jpg');
$imageBase64 = base64_encode($imageData);

// Upload face (person must exist first)
$response = $faceService->uploadFace('EMP001', $imageBase64, 1);

use Shaykhnazar\HikvisionIsapi\Services\FaceService;

$faceService = app(FaceService::class);

// Search face data with pagination
$results = $faceService->searchFace(
    page: 0,
    maxResults: 30,
    faceLibType: 'blackFD',
    fdid: 1,
    fpid: '31903791410044'
);

// Upload face data record with image file
$imageContent = file_get_contents('face.jpg');
$response = $faceService->uploadFaceDataRecord(
    fdid: 1,
    fpid: '31903791410044',
    imageContent: $imageContent,
    faceLibType: 'blackFD'
);

// Delete face search data
$faceService->deleteFaceSearch(fdid: 1, faceLibType: 'blackFD');

$personService = app(PersonService::class);

// Get total count
$total = $personService->count();

// Search with pagination (30 persons per page)
$persons = $personService->search(page: 0, maxResults: 30);

foreach ($persons as $person) {
    echo "{$person->employeeNo}: {$person->name}\n";
}

use Shaykhnazar\HikvisionIsapi\Services\CardService;
use Shaykhnazar\HikvisionIsapi\DTOs\Card;

$cardService = app(CardService::class);

$card = new Card(
    employeeNo: 'EMP001',
    cardNo: '1234567890',
    cardType: 'normal'
);

$response = $cardService->add($card);

use Shaykhnazar\HikvisionIsapi\Services\AccessControlService;

$accessControl = app(AccessControlService::class);

// Open door
$accessControl->openDoor(1);

// Get door status
$status = $accessControl->getDoorStatus(1);

// Close door
$accessControl->closeDoor(1);

use Shaykhnazar\HikvisionIsapi\Services\EventService;

$eventService = app(EventService::class);

$events = $eventService->search([
    'major' => 5,  // Access control
    'minor' => 75, // Face recognition
    'startTime' => now()->subDay()->toISOString(),
    'endTime' => now()->toISOString(),
], page: 0, maxResults: 50);

use Shaykhnazar\HikvisionIsapi\Services\EventNotificationService;

$eventNotificationService = app(EventNotificationService::class);

// Configure device to send all events to your webhook endpoint
$webhookUrl = 'https://your-api.com/api/webhooks/hikvision/events';

$response = $eventNotificationService->configureWebhook(
    webhookUrl: $webhookUrl,
    hostId: 1 // Host ID (1-8), default is 1
);

// Enable the webhook
$eventNotificationService->enableHttpHost(1);

$response = $eventNotificationService->configureHttpHost(
    url: 'https://your-api.com/api/webhooks/hikvision/events',
    id: 1,                      // Host ID (1-8)
    protocol: 'HTTPS',          // HTTP or HTTPS
    port: 443,                  // Port number
    httpAuthType: 'basic',      // none, basic, or digest
    username: 'webhook_user',   // Optional: for authentication
    password: 'webhook_pass',   // Optional: for authentication
    eventTypes: [               // Optional: specific event types (empty = all events)
        'AccessControllerEvent',
        'VideoMotion',
        'linedetection'
    ]
);

// Get webhook configuration
$config = $eventNotificationService->getHttpHost(1);

// Get all webhook configurations (supports up to 8 hosts)
$allConfigs = $eventNotificationService->getAllHttpHosts();

// Enable webhook
$eventNotificationService->enableHttpHost(1);

// Disable webhook
$eventNotificationService->disableHttpHost(1);

// Remove webhook configuration
$eventNotificationService->removeHttpHost(1);

// Get notification capabilities
$capabilities = $eventNotificationService->getCapabilities();

// Send a test event to configured webhook
$response = $eventNotificationService->testHttpNotification(1);

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class HikvisionWebhookController extends Controller
{
    /**
     * Receive events from Hikvision devices
     */
    public function handleEvent(Request $request)
    {
        // Hikvision sends events as XML
        $xmlData = $request->getContent();

        // Parse XML to array
        $xml = simplexml_load_string($xmlData);
        $event = json_decode(json_encode($xml), true);

        // Log the event
        Log::info('Hikvision Event Received', $event);

        // Process event based on type
        $eventType = $event['eventType'] ?? null;

        match($eventType) {
            'AccessControllerEvent' => $this->handleAccessControl($event),
            'faceDetection' => $this->handleFaceDetection($event),
            'VideoMotion' => $this->handleMotionDetection($event),
            default => Log::warning('Unknown event type', ['type' => $eventType])
        };

        // Return 200 OK to acknowledge receipt
        return response('OK', 200);
    }

    protected function handleAccessControl(array $event)
    {
        // Example: Handle access control event
        $employeeNo = $event['employeeNoString'] ?? null;
        $cardNo = $event['cardNo'] ?? null;
        $doorNo = $event['doorNo'] ?? null;

        Log::info('Access Control Event', [
            'employee' => $employeeNo,
            'card' => $cardNo,
            'door' => $doorNo,
            'time' => $event['dateTime'] ?? now()
        ]);

        // Your business logic here
        // - Record attendance
        // - Send notifications
        // - Update access logs
    }

    protected function handleFaceDetection(array $event)
    {
        // Handle face detection event
        Log::info('Face Detection Event', $event);
    }

    protected function handleMotionDetection(array $event)
    {
        // Handle motion detection event
        Log::info('Motion Detection Event', $event);
    }
}

// routes/api.php
Route::post('webhooks/hikvision/events', [HikvisionWebhookController::class, 'handleEvent'])
    ->name('hikvision.webhook');

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\EventNotificationService;

$devices = ['entrance', 'exit', 'canteen'];
$webhookUrl = 'https://your-api.com/api/webhooks/hikvision/events';

foreach ($devices as $deviceName) {
    $client = Hikvision::device($deviceName);
    $eventService = new EventNotificationService($client);

    // Configure webhook with device name in URL for identification
    $deviceWebhookUrl = $webhookUrl . '?device=' . $deviceName;

    $eventService->configureWebhook($deviceWebhookUrl);
    $eventService->enableHttpHost(1);

    Log::info("Webhook configured for device: {$deviceName}");
}

// Add authentication to webhook configuration
$eventNotificationService->configureHttpHost(
    url: 'https://your-api.com/api/webhooks/hikvision/events',
    id: 1,
    protocol: 'HTTPS',
    port: 443,
    httpAuthType: 'basic',
    username: env('HIKVISION_WEBHOOK_USER'),
    password: env('HIKVISION_WEBHOOK_PASSWORD')
);

// In your controller, validate the credentials
public function handleEvent(Request $request)
{
    // Laravel automatically handles basic auth with middleware
    // Or manually validate:
    if ($request->getUser() !== env('HIKVISION_WEBHOOK_USER') ||
        $request->getPassword() !== env('HIKVISION_WEBHOOK_PASSWORD')) {
        return response('Unauthorized', 401);
    }

    // Process event...
}

use Shaykhnazar\HikvisionIsapi\Facades\HikvisionIsapi;

// Get device info
$info = HikvisionIsapi::get('/ISAPI/System/deviceInfo');

// Custom endpoint
$response = HikvisionIsapi::post('/ISAPI/CustomEndpoint', [
    'key' => 'value'
]);

$deviceService = app(DeviceService::class);

$deviceService->getInfo();           // Get device information
$deviceService->getCapabilities();   // Get device capabilities
$deviceService->getStatus();         // Get device status
$deviceService->isOnline();          // Check if device is online

$personService = app(PersonService::class);

$personService->add(Person $person);              // Add person
$personService->update(Person $person);           // Update person
$personService->apply(Person $person);            // Apply person changes
$personService->search(int $page, int $maxResults); // Search persons
$personService->delete(array $employeeNos);       // Delete persons
$personService->count();                          // Count persons
$personService->getCapabilities();                // Get capabilities

$cardService = app(CardService::class);

$cardService->add(Card $card);                    // Add card
$cardService->update(Card $card);                 // Update card
$cardService->search(...);                        // Search cards
$cardService->delete(array $employeeNos);         // Delete cards
$cardService->deleteAll();                        // Delete all cards
$cardService->count(?string $employeeNo);         // Count cards
$cardService->batchAdd(array $cards);             // Batch add cards

$faceService = app(FaceService::class);

$faceService->uploadFace(string $employeeNo, string $imageBase64, int $fdid);
$faceService->deleteFace(int $fdid, int $fpid);
$faceService->searchFace(int $page, int $maxResults, string $faceLibType, ?int $fdid, ?string $fpid);
$faceService->deleteFaceSearch(int $fdid, string $faceLibType);
$faceService->uploadFaceDataRecord(int $fdid, string $fpid, string $imageContent, string $faceLibType);
$faceService->getLibraries();
$faceService->createLibrary(array $data);
$faceService->getCapabilities();

$fingerprintService = app(FingerprintService::class);

$fingerprintService->add(string $employeeNo, int $fingerprintId, string $data);
$fingerprintService->search(...);
$fingerprintService->capture(int $timeout);
$fingerprintService->delete(array $employeeNos);
$fingerprintService->getCapabilities();

$accessControl = app(AccessControlService::class);

$accessControl->openDoor(int $doorNo);
$accessControl->closeDoor(int $doorNo);
$accessControl->getDoorStatus(int $doorNo);

$eventService = app(EventService::class);

$eventService->search(array $conditions, int $page, int $maxResults);
$eventService->count(array $conditions);
$eventService->subscribe(array $eventTypes, int $heartbeat);

$eventNotificationService = app(EventNotificationService::class);

// Simple webhook setup
$eventNotificationService->configureWebhook(string $webhookUrl, int $hostId);

// Advanced configuration
$eventNotificationService->configureHttpHost(string $url, int $id, string $protocol, int $port, string $httpAuthType, ?string $username, ?string $password, array $eventTypes);

// Manage webhooks
$eventNotificationService->getHttpHost(int $id);
$eventNotificationService->getAllHttpHosts();
$eventNotificationService->enableHttpHost(int $id);
$eventNotificationService->disableHttpHost(int $id);
$eventNotificationService->removeHttpHost(int $id);

// Testing
$eventNotificationService->testHttpNotification(int $id);

// Capabilities
$eventNotificationService->getCapabilities();

use Shaykhnazar\HikvisionIsapi\DTOs\Person;
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

$person = new Person(
    employeeNo: 'EMP001',
    name: 'John Doe',
    userType: UserType::NORMAL,
    validEnabled: true,
    beginTime: '2025-01-01T00:00:00',
    endTime: '2025-12-31T23:59:59',
    doorRight: '1',
    rightPlan: [
        ['doorNo' => 1, 'planTemplateNo' => '1']
    ],
    email: '[email protected]',
    phoneNumber: '+1234567890',
    organizationId: 1,
    belongGroup: null
);

// Convert to array for API
$array = $person->toArray();

// Create from API response
$person = Person::fromArray($response);

use Shaykhnazar\HikvisionIsapi\DTOs\Card;

$card = new Card(
    employeeNo: 'EMP001',
    cardNo: '1234567890',
    cardType: 'normal',
    enabled: true
);

use Shaykhnazar\HikvisionIsapi\DTOs\Face;

$face = new Face(
    employeeNo: 'EMP001',
    faceData: base64_encode($imageData),
    faceLibId: 1,
    faceLibType: 'blackFD'
);

use Shaykhnazar\HikvisionIsapi\Enums\UserType;

UserType::NORMAL    // Normal user
UserType::VISITOR   // Visitor
UserType::BLOCKLIST // Blocklist user

// Get label
$label = UserType::NORMAL->label(); // "Normal User"

use Shaykhnazar\HikvisionIsapi\Enums\EventType;

EventType::ACCESS_GRANTED  // 0x01
EventType::ACCESS_DENIED   // 0x02
EventType::FACE_RECOGNIZED // 0x4b
EventType::CARD_SWIPED     // 0x05

// Get description
$desc = EventType::ACCESS_GRANTED->description(); // "Access Granted"

use Shaykhnazar\HikvisionIsapi\Exceptions\HikvisionException;
use Shaykhnazar\HikvisionIsapi\Exceptions\AuthenticationException;
use Shaykhnazar\HikvisionIsapi\Exceptions\DeviceNotFoundException;

try {
    $response = $personService->add($person);
} catch (AuthenticationException $e) {
    // Handle authentication errors
    Log::error('Authentication failed', ['error' => $e->getMessage()]);
} catch (DeviceNotFoundException $e) {
    // Handle device not found
    Log::error('Device not found', ['error' => $e->getMessage()]);
} catch (HikvisionException $e) {
    // Handle other Hikvision errors
    Log::error('Hikvision error', ['error' => $e->getMessage()]);
}

return [
    'default' => env('HIKVISION_DEFAULT_DEVICE', 'primary'),

    'devices' => [
        'primary' => [
            'ip' => env('HIKVISION_IP', '192.168.1.100'),
            'port' => env('HIKVISION_PORT', 80),
            'username' => env('HIKVISION_USERNAME', 'admin'),
            'password' => env('HIKVISION_PASSWORD'),
            'protocol' => env('HIKVISION_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_VERIFY_SSL', false),
        ],

        'entrance' => [
            'ip' => env('HIKVISION_ENTRANCE_IP', '192.168.1.101'),
            'port' => env('HIKVISION_ENTRANCE_PORT', 80),
            'username' => env('HIKVISION_ENTRANCE_USERNAME', 'admin'),
            'password' => env('HIKVISION_ENTRANCE_PASSWORD'),
            'protocol' => env('HIKVISION_ENTRANCE_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_ENTRANCE_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_ENTRANCE_VERIFY_SSL', false),
        ],

        'exit' => [
            'ip' => env('HIKVISION_EXIT_IP', '192.168.1.102'),
            'port' => env('HIKVISION_EXIT_PORT', 80),
            'username' => env('HIKVISION_EXIT_USERNAME', 'admin'),
            'password' => env('HIKVISION_EXIT_PASSWORD'),
            'protocol' => env('HIKVISION_EXIT_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_EXIT_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_EXIT_VERIFY_SSL', false),
        ],

        'canteen' => [
            'ip' => env('HIKVISION_CANTEEN_IP', '192.168.1.103'),
            'port' => env('HIKVISION_CANTEEN_PORT', 80),
            'username' => env('HIKVISION_CANTEEN_USERNAME', 'admin'),
            'password' => env('HIKVISION_CANTEEN_PASSWORD'),
            'protocol' => env('HIKVISION_CANTEEN_PROTOCOL', 'http'),
            'timeout' => env('HIKVISION_CANTEEN_TIMEOUT', 30),
            'verify_ssl' => env('HIKVISION_CANTEEN_VERIFY_SSL', false),
        ],
    ],
];

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// Use default device
$defaultClient = Hikvision::default();
$info = $defaultClient->get('/ISAPI/System/deviceInfo');

// Use specific devices
$entranceClient = Hikvision::device('entrance');
$exitClient = Hikvision::device('exit');
$canteenClient = Hikvision::device('canteen');

// Get device information from each terminal
$entranceInfo = $entranceClient->get('/ISAPI/System/deviceInfo');
$exitInfo = $exitClient->get('/ISAPI/System/deviceInfo');
$canteenInfo = $canteenClient->get('/ISAPI/System/deviceInfo');

// List all available devices
$devices = Hikvision::availableDevices();
// Returns: ['primary', 'entrance', 'exit', 'canteen']

// Check if device exists
if (Hikvision::hasDevice('entrance')) {
    // Work with entrance device
}

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\PersonService;
use Shaykhnazar\HikvisionIsapi\DTOs\Person;
use Shaykhnazar\HikvisionIsapi\Enums\UserType;

// Create person DTO
$person = new Person(
    employeeNo: 'EMP001',
    name: 'John Doe',
    userType: UserType::NORMAL,
    validEnabled: true,
    beginTime: now()->toISOString(),
    endTime: now()->addYear()->toISOString()
);

// Get device-specific clients
$entranceClient = Hikvision::device('entrance');
$exitClient = Hikvision::device('exit');
$canteenClient = Hikvision::device('canteen');

// Create person service for each device
$entrancePersonService = new PersonService($entranceClient);
$exitPersonService = new PersonService($exitClient);
$canteenPersonService = new PersonService($canteenClient);

// Add person to all devices
$entrancePersonService->add($person);
$exitPersonService->add($person);
$canteenPersonService->add($person);

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\PersonService;
use Shaykhnazar\HikvisionIsapi\Services\FaceService;
use Shaykhnazar\HikvisionIsapi\DTOs\Person;

class EmployeeSyncService
{
    public function syncToAllDevices(Person $person, string $faceImagePath): array
    {
        $results = [];
        $devices = Hikvision::availableDevices();

        foreach ($devices as $deviceName) {
            try {
                // Get device client
                $client = Hikvision::device($deviceName);

                // Create services for this device
                $personService = new PersonService($client);
                $faceService = new FaceService($client);

                // Add person
                $personService->add($person);

                // Upload face
                $imageData = file_get_contents($faceImagePath);
                $imageBase64 = base64_encode($imageData);
                $faceService->uploadFace($person->employeeNo, $imageBase64, 1);

                $results[$deviceName] = [
                    'success' => true,
                    'message' => 'Synced successfully',
                ];
            } catch (\Exception $e) {
                $results[$deviceName] = [
                    'success' => false,
                    'error' => $e->getMessage(),
                ];
            }
        }

        return $results;
    }
}

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// Get client for specific device (or default if null)
$client = Hikvision::device('entrance');
$client = Hikvision::device(); // Uses default device

// Get default device client
$defaultClient = Hikvision::default();

// Get all available device names
$devices = Hikvision::availableDevices();
// Returns: ['primary', 'entrance', 'exit', 'canteen']

// Check if device exists in configuration
$exists = Hikvision::hasDevice('entrance'); // true or false

// Reload devices from provider (useful for database-driven configs)
Hikvision::reload(); // Clears cache and reloads from source

// Clear cached clients (useful for testing)
Hikvision::clearClients();

// Register device at runtime (v1.3.0+)
Hikvision::registerDevice('temp_device', [
    'ip' => '192.168.1.150',
    'port' => 80,
    'username' => 'admin',
    'password' => 'password',
    'protocol' => 'http',
    'timeout' => 30,
    'verify_ssl' => false,
]);

// Switch device provider at runtime (v1.3.0+)
use Shaykhnazar\HikvisionIsapi\Client\Providers\DatabaseDeviceProvider;
$dbProvider = new DatabaseDeviceProvider(table: 'terminals');
Hikvision::setProvider($dbProvider);

use Shaykhnazar\HikvisionIsapi\Services\PersonService;

// This still works - uses default device
$personService = app(PersonService::class);
$person = $personService->add($newPerson);

// Migration: create_terminals_table.php
Schema::create('terminals', function (Blueprint $table) {
    $table->id();
    $table->string('name')->unique(); // Device identifier
    $table->string('ip');
    $table->integer('port')->default(80);
    $table->string('username');
    $table->string('password');
    $table->string('protocol')->default('http');
    $table->integer('timeout')->default(30);
    $table->boolean('verify_ssl')->default(false);
    $table->boolean('is_active')->default(true);
    $table->timestamps();
});

use Shaykhnazar\HikvisionIsapi\Client\Providers\DatabaseDeviceProvider;

public function register(): void
{
    // Bind custom device provider
    $this->app->singleton('hikvision.device.provider', function ($app) {
        return new DatabaseDeviceProvider(
            table: 'terminals',
            nameColumn: 'name',
            configColumns: [
                'ip' => 'ip',
                'port' => 'port',
                'username' => 'username',
                'password' => 'password',
                'protocol' => 'protocol',
                'timeout' => 'timeout',
                'verify_ssl' => 'verify_ssl',
            ],
            defaultDevice: 'primary',
            whereConditions: ['is_active' => true], // Only load active terminals
            cache: true, // Enable caching
            cacheTtl: 3600 // Cache for 1 hour
        );
    });
}

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Services\PersonService;

// Get all available terminals from database
$terminals = Hikvision::availableDevices();
// Returns: ['entrance', 'exit', 'canteen', 'office'] - loaded from DB

// Use specific terminal
$entranceClient = Hikvision::device('entrance');
$personService = new PersonService($entranceClient);

// Add person to entrance terminal
$personService->add($person);

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// After adding/updating terminals in database
Hikvision::reload(); // Clears cache and reloads from DB

use Shaykhnazar\HikvisionIsapi\Client\Providers\CallbackDeviceProvider;
use App\Models\Terminal;

// In your service provider
$this->app->singleton('hikvision.device.provider', function ($app) {
    return CallbackDeviceProvider::fromEloquent(
        query: Terminal::where('status', 'active')
                      ->where('company_id', auth()->user()->company_id),
        nameColumn: 'slug',
        configMap: [
            'ip' => 'ip_address',
            'port' => 'port',
            'username' => 'username',
            'password' => 'password',
            'protocol' => 'protocol',
            'timeout' => 'connection_timeout',
            'verify_ssl' => 'ssl_enabled',
        ]
    );
});

use Shaykhnazar\HikvisionIsapi\Client\Providers\CallbackDeviceProvider;
use App\Models\Terminal;

// In AppServiceProvider
$this->app->singleton('hikvision.device.provider', function ($app) {
    return new CallbackDeviceProvider(
        deviceNamesCallback: function () {
            // Only load terminals for current tenant
            $tenantId = auth()->user()->tenant_id;
            return Terminal::where('tenant_id', $tenantId)
                          ->where('is_active', true)
                          ->pluck('name')
                          ->toArray();
        },
        deviceConfigCallback: function (string $deviceName) {
            $tenantId = auth()->user()->tenant_id;
            $terminal = Terminal::where('tenant_id', $tenantId)
                               ->where('name', $deviceName)
                               ->first();

            if (!$terminal) {
                return null;
            }

            return [
                'ip' => $terminal->ip,
                'port' => $terminal->port,
                'username' => $terminal->username,
                'password' => decrypt($terminal->password), // Decrypt if encrypted
                'protocol' => $terminal->protocol,
                'timeout' => $terminal->timeout,
                'verify_ssl' => $terminal->verify_ssl,
            ];
        },
        defaultDevice: 'primary'
    );
});

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;

// Register a temporary device
Hikvision::registerDevice('temp_device', [
    'ip' => '192.168.1.150',
    'port' => 80,
    'username' => 'admin',
    'password' => 'password',
    'protocol' => 'http',
    'timeout' => 30,
    'verify_ssl' => false,
]);

// Use the temporary device
$client = Hikvision::device('temp_device');

use Shaykhnazar\HikvisionIsapi\Facades\Hikvision;
use Shaykhnazar\HikvisionIsapi\Client\Providers\DatabaseDeviceProvider;
use Shaykhnazar\HikvisionIsapi\Client\Providers\ConfigDeviceProvider;

// Switch to database provider
$dbProvider = new DatabaseDeviceProvider(table: 'terminals');
Hikvision::setProvider($dbProvider);

// Now all devices are loaded from database
$devices = Hikvision::availableDevices();

// Switch back to config provider
$configProvider = new ConfigDeviceProvider(config('hikvision'));
Hikvision::setProvider($configProvider);

$cardService = app(CardService::class);

$cards = [
    new Card('EMP001', '1234567890'),
    new Card('EMP002', '0987654321'),
    new Card('EMP003', '1122334455'),
];

$results = $cardService->batchAdd($cards);

/*
Returns:
[
    'total' => 3,
    'success' => 3,
    'failed' => 0,
    'errors' => []
]
*/

$personService = app(PersonService::class);
$total = $personService->count();
$perPage = 30;
$pages = ceil($total / $perPage);

for ($page = 0; $page < $pages; $page++) {
    $persons = $personService->search($page, $perPage);
    // Process persons...
}

use Shaykhnazar\HikvisionIsapi\Facades\HikvisionIsapi;

// GET request
$response = HikvisionIsapi::get('/ISAPI/CustomEndpoint', [
    'param1' => 'value1',
]);

// POST request
$response = HikvisionIsapi::post('/ISAPI/CustomEndpoint', [
    'key' => 'value',
]);

// PUT request
$response = HikvisionIsapi::put('/ISAPI/CustomEndpoint', [
    'key' => 'value',
]);

// DELETE request
$response = HikvisionIsapi::delete('/ISAPI/CustomEndpoint');
bash
php artisan vendor:publish --tag=hikvision-config
xml
<EventNotificationAlert>
    <eventType>AccessControllerEvent</eventType>
    <eventState>active</eventState>
    <eventDescription>Access Control Event</eventDescription>
    <dateTime>2025-10-30T14:30:00Z</dateTime>
    <ActivePost>
        <eventType>AccessControllerEvent</eventType>
        <employeeNoString>EMP001</employeeNoString>
        <name>John Doe</name>
        <cardNo>1234567890</cardNo>
        <doorNo>1</doorNo>
        <swipeResult>success</swipeResult>
    </ActivePost>
</EventNotificationAlert>