baseUrl = config('services.traccar.api_url'); $this->username = config('services.traccar.admin_username'); $this->password = config('services.traccar.admin_password'); $this->client = new Client([ 'timeout' => 30, 'headers' => [ 'Accept' => 'application/json', 'User-Agent' => 'Laravel-TraccarService/1.0', ], 'verify' => false, // For development only ]); } /** * Make authenticated request to Traccar API */ private function makeRequest(string $method, string $endpoint, array $data = []): array { try { $fullUrl = $this->baseUrl . $endpoint; $options = [ 'auth' => [$this->username, $this->password, 'basic'], 'headers' => [ 'Accept' => 'application/json', 'User-Agent' => 'Laravel-TraccarService/1.0', ], ]; if (!empty($data)) { $options['json'] = $data; $options['headers']['Content-Type'] = 'application/json'; } $response = $this->client->request($method, $fullUrl, $options); $responseBody = $response->getBody()->getContents(); $result = json_decode($responseBody, true); Log::info("Traccar API Request", [ 'method' => $method, 'endpoint' => $endpoint, 'full_url' => $fullUrl, 'status' => $response->getStatusCode(), 'response_length' => strlen($responseBody), 'response_preview' => substr($responseBody, 0, 200), 'content_type' => $response->getHeaderLine('Content-Type'), ]); // Handle empty responses or null JSON decode results if ($result === null && !empty($responseBody)) { Log::warning("Failed to decode JSON response", [ 'raw_response' => $responseBody, 'content_type' => $response->getHeaderLine('Content-Type'), ]); return []; } return $result ?? []; } catch (GuzzleException $e) { Log::error("Traccar API Error", [ 'method' => $method, 'endpoint' => $endpoint, 'full_url' => $this->baseUrl . $endpoint, 'error' => $e->getMessage(), ]); throw $e; } } // ===== SERVER METHODS ===== /** * Get server information */ public function getServerInfo(): array { return $this->makeRequest('GET', '/server'); } // ===== USER METHODS ===== /** * Get all users */ public function getUsers(): array { return $this->makeRequest('GET', '/users'); } /** * Create a new user in Traccar */ public function createUser(array $userData): array { return $this->makeRequest('POST', '/users', $userData); } /** * Update user in Traccar */ public function updateUser(int $userId, array $userData): array { return $this->makeRequest('PUT', "/users/{$userId}", $userData); } /** * Delete user from Traccar */ public function deleteUser(int $userId): bool { $this->makeRequest('DELETE', "/users/{$userId}"); return true; } // ===== DEVICE METHODS ===== /** * Get all devices */ public function getDevices(?int $userId = null): array { $endpoint = '/devices'; if ($userId) { $endpoint .= "?userId={$userId}"; } return $this->makeRequest('GET', $endpoint); } /** * Create a new device */ public function createDevice(array $deviceData): array { return $this->makeRequest('POST', '/devices', $deviceData); } /** * Update device */ public function updateDevice(int $deviceId, array $deviceData): array { return $this->makeRequest('PUT', "/devices/{$deviceId}", $deviceData); } /** * Delete device */ public function deleteDevice(int $deviceId): bool { $this->makeRequest('DELETE', "/devices/{$deviceId}"); return true; } // ===== POSITION METHODS ===== /** * Get latest positions for all devices */ public function getPositions(): array { return $this->makeRequest('GET', '/positions'); } /** * Get latest positions for specific devices */ public function getDevicePositions(int $deviceId, ?string $from = null, ?string $to = null): array { $params = ['deviceId' => $deviceId]; if ($from) $params['from'] = $from; if ($to) $params['to'] = $to; $query = http_build_query($params); $endpoint = "/positions?{$query}"; return $this->makeRequest('GET', $endpoint); } /** * Get latest positions for multiple devices */ public function getMultipleDevicePositions(array $deviceIds): array { if (empty($deviceIds)) { return []; } // Build query string for multiple device IDs $params = []; foreach ($deviceIds as $deviceId) { $params[] = "deviceId={$deviceId}"; } $query = implode('&', $params); $endpoint = "/positions?{$query}"; return $this->makeRequest('GET', $endpoint); } /** * Get real-time positions (latest for all user devices) */ public function getRealTimePositions(array $deviceIds = []): array { if (empty($deviceIds)) { // Get latest positions for all devices return $this->getPositions(); } // Get positions for specific devices return $this->getMultipleDevicePositions($deviceIds); } // ===== GEOFENCE METHODS ===== /** * Get all geofences */ public function getGeofences(): array { return $this->makeRequest('GET', '/geofences'); } /** * Create geofence */ public function createGeofence(array $geofenceData): array { return $this->makeRequest('POST', '/geofences', $geofenceData); } /** * Update geofence */ public function updateGeofence(int $geofenceId, array $geofenceData): array { return $this->makeRequest('PUT', "/geofences/{$geofenceId}", $geofenceData); } /** * Delete geofence */ public function deleteGeofence(int $geofenceId): bool { $this->makeRequest('DELETE', "/geofences/{$geofenceId}"); return true; } // ===== EVENT METHODS ===== /** * Get events */ public function getEvents(?int $deviceId = null, ?string $type = null): array { $params = []; if ($deviceId) $params['deviceId'] = $deviceId; if ($type) $params['type'] = $type; $query = http_build_query($params); $endpoint = '/events' . ($query ? "?{$query}" : ''); return $this->makeRequest('GET', $endpoint); } // ===== REPORT METHODS ===== /** * Get trip reports */ public function getTripReports(array $deviceIds, string $from, string $to): array { $params = [ 'deviceId' => $deviceIds, 'from' => $from, 'to' => $to ]; $query = http_build_query($params); return $this->makeRequest('GET', "/reports/trips?{$query}"); } /** * Get summary reports */ public function getSummaryReports(array $deviceIds, string $from, string $to): array { $params = [ 'deviceId' => $deviceIds, 'from' => $from, 'to' => $to ]; $query = http_build_query($params); return $this->makeRequest('GET', "/reports/summary?{$query}"); } // ===== COMMAND METHODS ===== /** * Send command to device */ public function sendCommand(array $commandData): array { return $this->makeRequest('POST', '/commands/send', $commandData); } /** * Get available command types */ public function getCommandTypes(): array { return $this->makeRequest('GET', '/commands/types'); } // ===== PERMISSION METHODS ===== /** * Link user to device */ public function linkUserDevice(int $userId, int $deviceId): bool { $this->makeRequest('POST', '/permissions', [ 'userId' => $userId, 'deviceId' => $deviceId ]); return true; } /** * Unlink user from device */ public function unlinkUserDevice(int $userId, int $deviceId): bool { $this->makeRequest('DELETE', '/permissions', [ 'userId' => $userId, 'deviceId' => $deviceId ]); return true; } // ===== UTILITY METHODS ===== /** * Test API connection */ public function testConnection(): bool { try { $this->getServerInfo(); return true; } catch (\Exception $e) { return false; } } /** * Clear cached data */ public function clearCache(): void { Cache::forget('traccar_positions'); } }