baseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); $this->username = env('THINGSBOARD_USERNAME', 'tenant1@thingsboard.org'); $this->password = env('THINGSBOARD_PASSWORD', 'tenant1'); } public function getToken() { if (Cache::has('thingsboard_token')) { return Cache::get('thingsboard_token'); } $response = Http::withHeaders([ // 'accept' => 'application/json', 'Content-Type' => 'application/json', ]) ->post("{$this->baseUrl}api/auth/login", [ 'username' => $this->username, 'password' => $this->password, ]); if ($response->successful()) { $token = $response->json('token'); Cache::put('thingsboard_token', $token, now()->addMinutes(15)); return $token; } else { Log::error("ThingsBoard Authentication Failed: " . $response->body()); throw new Exception('Unable to authenticate with ThingsBoard: ' . $response->body()); } } // public function createAsset(array $data) // { // $token = $this->getToken(); // $payload = [ // // 'entityType' => $data['entity_type'] ?? 'ASSET', // // 'createdTime' => $data['createdTime'] ?? now()->timestamp, // // 'tenantId' => [ // // 'id' => $data['tenantId'] ?? Str::uuid()->toString(), // // // 'entityType' => 'TENANT' // // ], // 'customerId' => [ // 'id' => $data['customerId'] ?? null, // 'entityType' => 'CUSTOMER' // ], // 'name' => $data['name'] ?? 'Default Asset', // 'type' => $data['type'] ?? 'Default Type', // 'label' => $data['label'] ?? '', // // 'assetProfileId' => [ // // 'id' => $data['assetProfileId'] ?? Str::uuid()->toString(), // // // 'entityType' => 'ASSET_PROFILE' // // ], // // 'externalId' => [ // // 'id' => $data['externalId'] ?? Str::uuid()->toString(), // // 'entityType' => 'ASSET' // // ], // 'version' => $data['version'] ?? '1.0', // 'additionalInfo' => $data['additionalInfo'] ?? ['description' => 'Default asset description'] // ]; // $response = Http::withHeaders([ // 'Authorization' => "Bearer $token", // 'Accept' => 'application/json', // 'Content-Type' => 'application/json', // ])->withBody(json_encode($payload), 'application/json') // ->post("{$this->baseUrl}/api/asset"); // Log::error('Error in creating asset: ' . $response); // // dd($response->json()); // if ($response->successful()) { // return $response->json(); // } else { // throw new Exception('Failed to create asset: ' . $response->body()); // } // } // public function createAsset(array $data) // { // $token = $this->getToken(); // $payload = [ // 'entityType' => $data['entity_type'], // Always 'ASSET' from backend // 'createdTime' => $data['createdTime'], // Always from backend // 'customerId' => [ // 'id' => $data['customerId'], // 'entityType' => 'CUSTOMER' // ], // 'name' => $data['name'], // 'type' => $data['type'], // 'label' => $data['label'], // 'version' => $data['version'], // 'additionalInfo' => $data['additionalInfo'], // ]; // $response = Http::withHeaders([ // 'Authorization' => "Bearer $token", // 'Accept' => 'application/json', // 'Content-Type' => 'application/json', // ])->withBody(json_encode($payload), 'application/json') // ->post("{$this->baseUrl}/api/asset"); // if ($response->successful()) { // return $response->json(); // } else { // Log::error('Error in creating asset: ' . $response->body()); // throw new Exception('Failed to create asset: ' . $response->body()); // } // } public function createAsset(array $data) { $token = $this->getToken(); $payload = [ 'entityType' => $data['entity_type'], // Always 'ASSET' from backend 'createdTime' => $data['createdTime'], 'customerId' => [ 'id' => $data['customerId'], 'entityType' => 'CUSTOMER' ], 'name' => $data['name'], 'type' => $data['type'], 'label' => $data['label'], // 'version' => removed to let backend default to 1 // 'additionalInfo' => $data['additionalInfo'], 'additionalInfo' => ['description' => $data['additionalInfo'] ?? 'User description'], ]; $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', 'Content-Type' => 'application/json', ])->withBody(json_encode($payload), 'application/json') ->post("{$this->baseUrl}api/asset"); if ($response->successful()) { return $response->json(); } else { Log::error('Error in creating asset: ' . $response->body()); throw new Exception('Failed to create asset: ' . $response->body()); } } public function createOrUpdateCustomer(array $data) { $token = $this->getToken(); // Log::info('Getting data before payload', ['data' => json_encode($data, JSON_PRETTY_PRINT)]); $payload = [ 'title' => $data['title'] ?? 'Default Title', 'email' => $data['email'] ?? 'default@example.com', 'country' => $data['country'] ?? 'India', 'state' => $data['state'] ?? 'Karnataka', 'city' => $data['city'] ?? 'Bangalore', 'zip' => $data['zip'] ?? '560001', 'name' => $data['name'] ?? 'John Doe', 'address' => $data['address'] ?? '123, 4th Cross, 5th Main', 'address2' => $data['address2'] ?? 'Near Park', 'phone' => $data['phone'] ?? '1234567890', 'version' => $data['version'] ?? '794665488', 'additionalInfo' => [ 'description' => $data['additionalInfo'] ?? 'User description' ], ]; if (!empty($data['id']) && is_array($data['id']) && isset($data['id']['id'])) { $payload['id'] = [ 'id' => $data['id']['id'], 'entityType' => 'CUSTOMER' ]; } // Check if `tenantId` exists and assign correctly if (!empty($data['tenantId']) && is_array($data['tenantId']) && isset($data['tenantId']['id'])) { $payload['tenantId'] = [ 'id' => $data['tenantId']['id'], 'entityType' => 'TENANT', ]; } // Log::info('Final Payload:', ['payload' => json_encode($payload, JSON_PRETTY_PRINT)]); $url = "{$this->baseUrl}api/customer"; $method = 'post'; // Send request $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', 'Content-Type' => 'application/json', ])->$method($url, $payload); if ($response->successful()) { return $response->json(); } else { throw new Exception('Failed to process customer: ' . $response->body()); } } public function createUser(array $data) { try { $token = $this->getToken(); // Validate required fields if (!isset($data['tenant_id'])) { throw new \Exception('tenant_id is required'); } $randomNumber = rand(1000, 9999); $email = "dummy{$randomNumber}@example.com"; // Prepare the payload with required fields $payload = [ 'email' => $email?? '', 'authority' => $data['authority'] ?? 'CUSTOMER_USER', 'firstName' => $data['first_name'] ?? '', 'lastName' => $data['last_name'] ?? '', 'name' => $data['name'] ?? ($data['first_name'] . ' ' . $data['last_name'] ?? ''), 'phone' => $data['phone'] ?? '', 'tenantId' => [ 'id' => 'bbab7c17-2f19-4eff-9ce7-63870e02b522', 'entityType' => 'TENANT' ], 'additionalInfo' => [ 'description' => $data['description'] ?? '' ] ]; // Only add customerId if provided if (!empty($data['customer_id'])) { $payload['customerId'] = [ 'id' => $data['customer_id'], 'entityType' => 'CUSTOMER' ]; } $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'accept' => 'application/json', 'Content-Type' => 'application/json', ]) ->timeout(30) ->post("{$this->baseUrl}api/user", $payload); if ($response->successful()) { return $response->json(); } // Log the full error details $errorDetails = [ 'status' => $response->status(), 'response' => $response->json() ?? $response->body(), 'payload' => $payload ]; Log::error('ThingsBoard API Error', $errorDetails); return [ 'error' => true, 'message' => 'Failed to create user in ThingsBoard', 'details' => $errorDetails ]; } catch (\Exception $e) { Log::error('ThingsBoard Service Exception: ' . $e->getMessage()); return [ 'error' => true, 'message' => $e->getMessage(), 'details' => 'Failed to process user creation' ]; } } public function deleteAsset(array $data) { $token = $this->getToken(); if (!isset($data['assetId']) || empty($data['assetId'])) { throw new Exception('Asset ID is required for deletion.'); } $assetId = $data['assetId']; $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', 'Content-Type' => 'application/json', ])->delete("{$this->baseUrl}api/asset/{$assetId}"); Log::info('Asset Deletion Response: ' . $response); if ($response->successful()) { return [ 'success' => true, 'message' => 'Asset deleted successfully.', 'data' => $response->json() ]; } else { throw new Exception('Failed to delete asset: ' . $response->body()); } } public function assignAssetToUser(array $data) { $token = $this->getToken(); // Validate required parameters if (!isset($data['assetId']) || empty($data['assetId'])) { throw new Exception('Asset ID is required.'); } if (!isset($data['userId']) || empty($data['userId'])) { throw new Exception('User ID is required.'); } $assetId = $data['assetId']; $userId = $data['userId']; // dd($data); // Retrieve user details to get the customer ID $user = User::find($userId); if (!$user) { throw new Exception('User not found.'); } // Get the ThingsBoard customer ID linked to the user // $customerId = $user->userId ?? null; $customerId = $user->userId ?? null; // ✅ Use the correct column name if (!$customerId) { throw new Exception('User does not have an associated customer ID.'); } // API request to assign asset to customer (based on user's customer ID) $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', 'Content-Type' => 'application/json', ])->post("{$this->baseUrl}api/customer/{$customerId}/asset/{$assetId}"); // Log the response for debugging purposes Log::info('Asset Assignment Response: ' . $response->body()); // Handle API responses if ($response->successful()) { return [ 'success' => true, 'message' => 'Asset assigned to user successfully.', 'data' => $response->json() ]; } else { throw new Exception('Failed to assign asset: ' . $response->body()); } } public function deleteCustomer(array $data) { $token = $this->getToken(); $url = "{$this->baseUrl}api/customer/{$data['customerId']}"; $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', ])->delete($url); // If response body is empty, assume success if ($response->status() === 200 && empty($response->body())) { return ['message' => 'Customer deleted successfully']; } if ($response->successful()) { return $response->json(); } else { throw new Exception('Failed to create customer: ' . $response->body()); } throw new Exception('Failed to create user: ' . $response->body()); } public function listUsers() { $token = $this->getToken(); $response = Http::withHeaders([ 'X-Authorization' => "Bearer $token", 'accept' => 'application/json', 'Content-Type' => 'application/json', ])->get("{$this->baseUrl}api/users?pageSize=100&page=0"); if ($response->successful()) { return $response->json(); } else { throw new Exception('Failed to fetch users: ' . $response->body()); } } public function deleteUser($userId) { try { $token = $this->getToken(); $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'accept' => 'application/json', ])->delete("{$this->baseUrl}api/user/{$userId}"); if ($response->failed()) { Log::error('ThingsBoard deletion failed - Status: ' . $response->status() . ' - Body: ' . $response->body()); return [ 'error' => true, 'message' => $response->status() === 404 ? 'User not found in ThingsBoard' : 'Failed to delete from ThingsBoard', 'details' => $response->json() ?? null, 'status' => $response->status() ]; } return [ 'success' => true, 'data' => $response->json(), 'status' => 200 ]; } catch (Exception $e) { Log::error('ThingsBoard deletion exception: ' . $e->getMessage()); return [ 'error' => true, 'message' => 'Exception during ThingsBoard deletion', 'details' => $e->getMessage() ]; } } // public function activateUser(User $user, string $password, string $activateToken) // { // try { // $payload = [ // 'activateToken' => $activateToken, // 'password' => $password // ]; // $activationUrl = "{$this->baseUrl}/api/noauth/activate"; // $response = Http::withHeaders([ // 'Content-Type' => 'application/json', // ])->post($activationUrl, $payload); // if (!$response->successful()) { // Log::error("Failed to activate user in ThingsBoard. Error: " . $response->body()); // throw new \Exception('Failed to activate user: ' . $response->body()); // } // Log::info("User activated successfully in ThingsBoard for User ID: {$user->id}"); // } catch (\Exception $e) { // Log::error("Error activating user in ThingsBoard for User ID: {$user->id}. Exception: " . $e->getMessage()); // throw $e; // } // } public function activateUser(User $user, string $password, string $activateToken) { try { // $dummyEmail = 'dummy+' . $user->id . '@example.com'; $token = $this->getToken(); // Step 1: Search for existing user by real email $searchResponse = Http::withHeaders([ 'Authorization' => "Bearer $token", 'accept' => 'application/json' ])->get("{$this->baseUrl}api/users?pageSize=1&page=0&textSearch={$user->email}"); if ($searchResponse->successful() && !empty($searchResponse['data'])) { $tbUser = $searchResponse['data'][0]; $tbUserId = $tbUser['id']['id']; // Step 2: Update user email to dummy email Http::withHeaders([ 'Authorization' => "Bearer $token", 'Content-Type' => 'application/json' ])->post("{$this->baseUrl}api/user", [ 'id' => ['id' => $tbUserId], // 'email' => $dummyEmail, 'authority' => $tbUser['authority'], 'firstName' => $tbUser['firstName'] ?? '', 'lastName' => $tbUser['lastName'] ?? '', 'tenantId' => $tbUser['tenantId'], 'customerId' => $tbUser['customerId'], 'additionalInfo' => $tbUser['additionalInfo'] ?? null, ]); // Log::info("ThingsBoard user email updated to dummy: {$dummyEmail}"); } // Step 3: Activate account using dummy email $activationPayload = [ 'activateToken' => $activateToken, 'password' => $password, // 'email' => $dummyEmail ]; $activationUrl = "{$this->baseUrl}api/noauth/activate"; $response = Http::withHeaders([ 'Content-Type' => 'application/json', ])->post($activationUrl, $activationPayload); if (!$response->successful()) { Log::error("Activation failed. Response: " . $response->body()); throw new \Exception('Failed to activate user: ' . $response->body()); } // Log::info("User activated in ThingsBoard with dummy email: {$dummyEmail}"); } catch (\Exception $e) { Log::error("Error during ThingsBoard activation. Exception: " . $e->getMessage()); throw $e; } } public function getUserByEmailThingsBoard(string $email) { Log::info("Fetching ThingsBoard ID by email: $email"); $token = $this->getToken(); // First, fetch the ThingsBoard ID by email $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'accept' => 'application/json' ])->get("http://65.0.131.117:8080/api/users?pageSize=1&page=0&textSearch=$email"); if ($response->successful()) { $data = $response->json()['data'] ?? []; if (!empty($data)) { $thingsboardUserId = $data[0]['id']['id']; Log::info("Found ThingsBoard ID: $thingsboardUserId"); // Now fetch user by ID $userResponse = Http::withHeaders([ 'Authorization' => "Bearer $token", 'accept' => 'application/json' ])->get("http://65.0.131.117:8080/api/user/$thingsboardUserId"); if ($userResponse->successful()) { return [ 'status' => true, 'user' => $userResponse->json(), 'dashboard_url' => 'http://65.0.131.117:8080/dashboard' ]; } else { Log::error("Failed to fetch user by ID. Status: " . $userResponse->status()); return [ 'status' => false, 'message' => 'User not found in ThingsBoard by ID.' ]; } } } Log::error("Failed to fetch ThingsBoard ID. Status: " . $response->status()); return [ 'status' => false, 'message' => 'User not found in ThingsBoard by email.' ]; } public function dashboardAdmin() { $token = $this->getToken(); $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'accept' => 'application/json', ])->get("{$this->baseUrl}api/users?pageSize=100&page=0"); if ($response->successful()) { return $response->json(); } else { throw new Exception('Failed to fetch users: ' . $response->body()); } } }