shaykhnazar/hikvision-isapi
最新稳定版本:v1.5.4
Composer 安装命令:
composer require shaykhnazar/hikvision-isapi
包简介
Laravel package for Hikvision ISAPI Face Recognition Terminals integration
README 文档
README
A clean, modern Laravel package for integrating with Hikvision ISAPI Face Recognition Terminals and access control devices. Supports multi-device management, universal device providers (config, database, API), multi-tenant architectures, and real-time event webhooks.
Features
- Real-Time Event Webhooks: Configure devices to push events to your API endpoints (v1.4.0+)
- Multi-Device Support: Manage unlimited Hikvision terminals simultaneously (v1.2.0+)
- Universal Device Providers: Load devices from config, database, API, or custom sources (v1.3.0+)
- Multi-Tenant Ready: Tenant-scoped device loading with runtime registration (v1.3.0+)
- Device Management: Get device info, status, and capabilities
- Person Management: Add, update, search, and delete persons
- Card Management: Handle access cards with full CRUD operations
- Face Recognition: Upload and manage face images with advanced search (v1.1.0+)
- Fingerprint Support: Register and manage fingerprints
- Access Control: Control doors remotely
- Event Handling: Search and subscribe to access events
- Event Notifications: HTTP webhooks for real-time event delivery (v1.4.0+)
- Clean Architecture: SOLID principles, dependency injection, contracts
- Type Safety: PHP 8.2+ features (enums, readonly properties)
- Performance: Built-in caching with configurable TTL (v1.3.0+)
- XML/JSON Support: Automatic format detection and conversion (v1.4.0+)
- Laravel 12: Full Laravel 12.x support with service provider and facade
Table of Contents
- Requirements
- Installation
- Configuration
- Quick Start
- Event Webhooks & Notifications
- Multi-Device Support
- Services Overview
- DTOs (Data Transfer Objects)
- Enums
- Error Handling
- Advanced Usage
- Testing
- Troubleshooting
- Security
- Contributing
- Changelog
Requirements
- PHP ^8.2
- Laravel ^12.0
- Guzzle HTTP ^7.8
- ext-curl
- ext-json
Installation
Install the package via Composer:
composer require shaykhnazar/hikvision-isapi
Publish the configuration file:
php artisan vendor:publish --tag=hikvision-config
Configuration
Add these environment variables to your .env file:
HIKVISION_IP=192.168.1.100 HIKVISION_PORT=80 HIKVISION_USERNAME=admin HIKVISION_PASSWORD=your_password HIKVISION_PROTOCOL=http HIKVISION_TIMEOUT=30 HIKVISION_VERIFY_SSL=false HIKVISION_FORMAT=json
Configuration File
The published config/hikvision.php supports multiple devices:
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'), ], ];
Quick Start
Check Device Status
use Shaykhnazar\HikvisionIsapi\Services\DeviceService; $deviceService = app(DeviceService::class); if ($deviceService->isOnline()) { $info = $deviceService->getInfo(); echo "Device Model: " . $info['DeviceInfo']['model']; }
Add a Person
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);
Upload Face Image
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);
Search and Manage Face Data
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');
Search Persons
$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"; }
Add Card
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);
Control Doors
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);
Search Events
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);
Event Webhooks & Notifications (v1.4.0+)
Configure Hikvision devices to automatically push events (access granted, face recognized, etc.) to your application's webhook endpoint in real-time. This eliminates the need for polling and provides instant event notifications.
Configure Webhook Endpoint
The EventNotificationService allows you to configure HTTP event notifications on Hikvision devices:
use Shaykhnazar\HikvisionIsapi\Services\EventNotificationService; $eventNotificationService = app(EventNotificationService::class);
Simple Webhook Setup
The easiest way to set up a webhook is using the configureWebhook() method:
// 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);
Advanced Webhook Configuration
For more control over webhook configuration, use configureHttpHost():
$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' ] );
Managing Webhook Hosts
// 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();
Testing Webhooks
Test if your webhook endpoint is reachable from the device:
// Send a test event to configured webhook $response = $eventNotificationService->testHttpNotification(1);
Receiving Webhook Events
Create a controller to receive webhook events from Hikvision devices:
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); } }
Route setup:
// routes/api.php Route::post('webhooks/hikvision/events', [HikvisionWebhookController::class, 'handleEvent']) ->name('hikvision.webhook');
Multi-Device Webhook Setup
Configure webhooks for multiple devices:
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}"); }
Webhook Security
Protect your webhook endpoint:
// 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... }
Webhook Event Examples
Access Control Event (Face Recognition):
<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>
Motion Detection Event:
<EventNotificationAlert> <eventType>VideoMotion</eventType> <eventState>active</eventState> <dateTime>2025-10-30T14:35:00Z</dateTime> </EventNotificationAlert>
Using the Facade
use Shaykhnazar\HikvisionIsapi\Facades\HikvisionIsapi; // Get device info $info = HikvisionIsapi::get('/ISAPI/System/deviceInfo'); // Custom endpoint $response = HikvisionIsapi::post('/ISAPI/CustomEndpoint', [ 'key' => 'value' ]);
Services Overview
DeviceService
$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
$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
$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
$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
$fingerprintService = app(FingerprintService::class); $fingerprintService->add(string $employeeNo, int $fingerprintId, string $data); $fingerprintService->search(...); $fingerprintService->capture(int $timeout); $fingerprintService->delete(array $employeeNos); $fingerprintService->getCapabilities();
AccessControlService
$accessControl = app(AccessControlService::class); $accessControl->openDoor(int $doorNo); $accessControl->closeDoor(int $doorNo); $accessControl->getDoorStatus(int $doorNo);
EventService
$eventService = app(EventService::class); $eventService->search(array $conditions, int $page, int $maxResults); $eventService->count(array $conditions); $eventService->subscribe(array $eventTypes, int $heartbeat);
EventNotificationService
$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();
DTOs (Data Transfer Objects)
Person DTO
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: 'john@example.com', phoneNumber: '+1234567890', organizationId: 1, belongGroup: null ); // Convert to array for API $array = $person->toArray(); // Create from API response $person = Person::fromArray($response);
Card DTO
use Shaykhnazar\HikvisionIsapi\DTOs\Card; $card = new Card( employeeNo: 'EMP001', cardNo: '1234567890', cardType: 'normal', enabled: true );
Face DTO
use Shaykhnazar\HikvisionIsapi\DTOs\Face; $face = new Face( employeeNo: 'EMP001', faceData: base64_encode($imageData), faceLibId: 1, faceLibType: 'blackFD' );
Enums
UserType
use Shaykhnazar\HikvisionIsapi\Enums\UserType; UserType::NORMAL // Normal user UserType::VISITOR // Visitor UserType::BLOCKLIST // Blocklist user // Get label $label = UserType::NORMAL->label(); // "Normal User"
EventType
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"
Error Handling
All exceptions extend HikvisionException:
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()]); }
Multi-Device Support
The package supports managing multiple Hikvision devices simultaneously. This is useful when you have multiple terminals at different locations (entrance, exit, canteen, etc.).
Device Sources Supported:
- ✅ Config files (default)
- ✅ Database tables
- ✅ Custom callbacks (API, Redis, cache, etc.)
- ✅ Runtime registration
Configuration from Config Files (Default)
Configure multiple devices in config/hikvision.php:
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), ], ], ];
Environment Variables
Add device-specific environment variables to .env:
# Primary Device (Default) HIKVISION_DEFAULT_DEVICE=primary HIKVISION_IP=192.168.1.100 HIKVISION_PORT=80 HIKVISION_USERNAME=admin HIKVISION_PASSWORD=your_password # Entrance Device HIKVISION_ENTRANCE_IP=192.168.1.101 HIKVISION_ENTRANCE_PORT=80 HIKVISION_ENTRANCE_USERNAME=admin HIKVISION_ENTRANCE_PASSWORD=entrance_password # Exit Device HIKVISION_EXIT_IP=192.168.1.102 HIKVISION_EXIT_PORT=80 HIKVISION_EXIT_USERNAME=admin HIKVISION_EXIT_PASSWORD=exit_password # Canteen Device HIKVISION_CANTEEN_IP=192.168.1.103 HIKVISION_CANTEEN_PORT=80 HIKVISION_CANTEEN_USERNAME=admin HIKVISION_CANTEEN_PASSWORD=canteen_password
Using Multiple Devices with Facade
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 }
Using Multiple Devices with Services
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);
Syncing Employee to Multiple Devices
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; } }
Device Manager Methods
The DeviceManager provides the following methods:
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);
Backward Compatibility
The package maintains 100% backward compatibility. If you're using the default device setup, your existing code will work without any changes:
use Shaykhnazar\HikvisionIsapi\Services\PersonService; // This still works - uses default device $personService = app(PersonService::class); $person = $personService->add($newPerson);
Loading Devices from Database
For applications that store terminal configurations in database (multi-tenant, dynamic terminals, etc.), use the DatabaseDeviceProvider:
Step 1: Create Terminals Table
// 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(); });
Step 2: Register Database Provider
In your AppServiceProvider or custom service provider:
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 ); }); }
Step 3: Use Terminals from Database
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);
Step 4: Reload Devices When Database Changes
use Shaykhnazar\HikvisionIsapi\Facades\Hikvision; // After adding/updating terminals in database Hikvision::reload(); // Clears cache and reloads from DB
Using Eloquent Models with CallbackProvider
For more complex scenarios with Eloquent relationships:
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', ] ); });
Multi-Tenant Support Example
For multi-tenant applications where each tenant has their own terminals:
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' ); });
Runtime Device Registration
Register devices dynamically at runtime:
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');
Switching Providers at Runtime
Change device provider dynamically:
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);
Advanced Usage
Batch Operations
$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' => [] ] */
Pagination
$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... }
Custom HTTP Requests
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');
Testing
# Run tests ./vendor/bin/phpunit # Run specific test file ./vendor/bin/phpunit tests/Feature/PersonServiceTest.php # Run with coverage ./vendor/bin/phpunit --coverage-html coverage
Troubleshooting
Authentication Failed (401)
Check your credentials in .env:
# Test with curl
curl -v --digest -u admin:password http://192.168.1.100/ISAPI/System/deviceInfo
Connection Timeout
- Verify device IP and network connectivity
- Increase timeout in config:
HIKVISION_TIMEOUT=60 - Check firewall rules
Face Upload Fails
- Ensure image is JPEG format
- Check image size (max 200KB)
- Verify person exists on device first
- Image quality should be good with clear face
Device Not Found
- Check IP address in
.env - Verify device is powered on
- Ensure device is on same network
Security
- Store credentials in
.envfile (never commit) - Use HTTPS in production
- Enable SSL verification with valid certificates
- Implement rate limiting on your API endpoints
- Validate all user input
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Follow PSR-12 coding standards
- Submit a pull request
Changelog
v1.4.0 (2025-10-30)
- EventNotificationService: New service for configuring HTTP event notifications (webhooks)
- Real-Time Webhooks: Configure devices to push events to your API endpoints automatically
- XML Support: Added
putXml()method to HikvisionClient for XML-only endpoints - HTTP Client Enhancements:
- Added
arrayToXml()method for converting arrays to XML format - Added
xmlToArray()method for parsing XML responses - Automatic XML/JSON format detection based on Content-Type
- Added
- Event Notification Methods:
configureWebhook()- Simple one-line webhook setupconfigureHttpHost()- Advanced webhook configuration with authenticationenableHttpHost()/disableHttpHost()- Enable/disable webhookstestHttpNotification()- Test webhook connectivitygetCapabilities()- Get notification capabilities
- Dependencies: Added
ext-simplexmlandext-libxmlfor XML processing - Multi-Device Webhooks: Configure webhooks for multiple devices simultaneously
- Webhook Security: Support for HTTP Basic and Digest authentication
- 100% backward compatible with v1.3.0
v1.3.0 (2025-10-13)
- Universal Device Providers: Framework for loading devices from any source
- DatabaseDeviceProvider: Load terminals from database tables with built-in caching
- CallbackDeviceProvider: Maximum flexibility with custom callbacks (API, Redis, etc.)
- Multi-Tenant Support: Tenant-scoped device loading and isolation
- Runtime Device Registration: Register devices dynamically at runtime
- Provider Switching: Change device providers on-the-fly
- Hot Reload: Update database-driven configurations without restart
- Configurable Caching: Built-in cache support with TTL control
- 100% backward compatible with v1.2.0
v1.2.0 (2025-10-13)
- Multi-Device Support: Manage unlimited Hikvision devices simultaneously
- DeviceManager: Central manager with lazy initialization and caching
- New Hikvision Facade: Multi-device access with
Hikvision::device() - Device Discovery: List and validate configured devices
- Device-Specific Clients: Automatic client caching per device
- 100% backward compatible with single-device setups
v1.1.0 (2025-10-13)
- Face Search Functionality: Search face data with pagination support
- Face Data Record Upload: Multipart/form-data support for face images
- Fixed PersonService Delete Endpoint: Updated to match ISAPI specification
- Configuration Validation: Required username/password validation
- Extended HTTP Client: Added multipart form-data upload support
- Enhanced error handling and validation
v1.0.0 (2025-10-09)
- Initial release
- Full ISAPI support
- Person, Card, Face, Fingerprint management
- Access control and event handling
- Laravel 12.x support
- PHP 8.2+ with modern features
License
This package is open-sourced software licensed under the MIT license.
Credits
- Author: Shaykhnazar
- Email: shaykhnazar@gmail.com
Support
For issues, questions, or contributions:
- GitHub Issues: https://github.com/shaykhnazar/hikvision-isapi/issues
- Email: shaykhnazar@gmail.com
Disclaimer
This package is designed for legitimate access control systems and defensive security purposes only. Do not use for malicious purposes.
Made with ❤️ for the Laravel community
统计信息
- 总下载量: 66
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 6
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-10