adminService = $adminService; $this->baseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); $this->username = env('THINGSBOARD_USERNAME', 'tenant1@thingsboard.org'); $this->password = env('THINGSBOARD_PASSWORD', 'tenant1'); } private $baseUrl; private $username; private $password; 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 getAdminAlarm($data) { try { $token = $this->adminService->getToken(); if (!$token) { Log::error("Failed to authenticate with ThingsBoard."); return []; } $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', ])->get("http://65.0.131.117:8080/api/v2/alarms?pageSize=10&page=0"); if (!$response->successful()) { Log::error("Failed to fetch ThingsBoard devices: " . $response->body()); return []; } return $response->json()['data'] ?? []; } catch (\Exception $e) { Log::error("Error fetching ThingsBoard devices: " . $e->getMessage()); return []; } } // public function getTelemetryData($devices, $startTs, $endTs, $limit = 100) // { // try { // // Get ThingsBoard token from AdminService // $token = $this->adminService->getToken(); // if (!$token) { // Log::error("Failed to authenticate with ThingsBoard."); // return ['error' => 'Authentication failed']; // } // $baseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); // $telemetryData = []; // foreach ($devices as $device) { // $deviceToken = $device->token; // // Include asset_id, device_profile_id, and device name // $assetId = $device->asset_id; // $deviceProfileId = $device->device_profile_id; // $deviceName = $device->name; // if (!$deviceToken) { // Log::warning("Device token missing for device: {$deviceName} (ID: {$device->id})"); // continue; // } // $keys = $device->timeseriesKeys->pluck('key_name')->implode(','); // if (empty($keys)) { // Log::warning("No telemetry keys found for device: {$deviceName} (Token: {$deviceToken})"); // continue; // } // // Make the telemetry API call // $response = Http::withHeaders([ // 'X-Authorization' => "Bearer $token", // 'Accept' => 'application/json', // ])->get("{$baseUrl}/api/plugins/telemetry/DEVICE/{$deviceToken}/values/timeseries", [ // 'keys' => $keys, // 'startTs' => $startTs, // 'endTs' => $endTs, // 'limit' => $limit, // 'useStrictDataTypes' => 'false', // ]); // if (!$response->successful()) { // Log::error("Failed to fetch telemetry for device: {$deviceName} (Token: {$deviceToken})"); // continue; // } // $data = $response->json(); // // Format telemetry data with asset_id, device_profile_id, and name as key // $formattedTelemetry = []; // if (!empty($data)) { // foreach ($data as $key => $values) { // foreach ($values as $item) { // $formattedTelemetry[] = [ // 'key' => $key, // 'value' => $item['value'], // 'ts' => $item['ts'] // ]; // } // } // } // $telemetryData[] = [ // 'asset_id' => $assetId, // 'device_profile_id' => $deviceProfileId, // 'name' => $deviceName, // 'telemetry' => $formattedTelemetry, // ]; // } // return $telemetryData; // } catch (\Exception $e) { // Log::error("Error fetching telemetry data: " . $e->getMessage()); // return ['error' => 'Failed to fetch telemetry data']; // } // } // public function getTelemetryData($devices, $startTs, $endTs) // { // $token = $this->adminService->getToken(); // if (!$token) { // Log::error('Failed to fetch ThingsBoard token'); // return ['error' => 'Failed to fetch ThingsBoard token']; // } // $baseUrl = env('THINGSBOARD_URL'); // $headers = [ // 'Authorization: Bearer ' . $token, // 'accept: application/json' // ]; // $allTelemetry = []; // foreach ($devices as $device) { // $deviceId = $device->id; // $keys = $device->timeseriesKeys->pluck('key_name')->filter()->implode(','); // if (empty($keys)) { // Log::warning("No telemetry keys found for device: {$device->name}"); // $allTelemetry[$deviceId] = [ // 'status' => 'error', // 'message' => 'No telemetry keys found' // ]; // continue; // } // $url = "$baseUrl/api/plugins/telemetry/DEVICE/{$deviceId}/values/timeseries" // . "?keys={$keys}&startTs={$startTs}&endTs={$endTs}&limit=100"; // $ch = curl_init($url); // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // $response = curl_exec($ch); // $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // $error = curl_error($ch); // curl_close($ch); // if ($error || $httpCode !== 200) { // Log::error("Failed to fetch telemetry for device: {$device->name} (ID: {$deviceId})", [ // 'http_code' => $httpCode, // 'error' => $error, // 'url' => $url, // 'response' => $response // ]); // $allTelemetry[$deviceId] = [ // 'status' => 'error', // 'message' => "Failed to fetch telemetry. HTTP Code: $httpCode, Error: $error" // ]; // continue; // } // $telemetry = json_decode($response, true); // if (json_last_error() !== JSON_ERROR_NONE) { // Log::error("Failed to decode telemetry response for device: {$device->name}", [ // 'response' => $response // ]); // $allTelemetry[$deviceId] = [ // 'status' => 'error', // 'message' => 'Invalid telemetry response format' // ]; // continue; // } // $allTelemetry[$deviceId] = [ // 'status' => 'success', // 'telemetry' => $telemetry // ]; // } // return $allTelemetry; // Return telemetry data mapped by device_id // } public function getTelemetryData($device, $keyNames, $startTs, $endTs) { $token = $this->adminService->getToken(); if (!$token) { Log::error('Failed to fetch ThingsBoard token'); return ['error' => 'Failed to fetch ThingsBoard token']; } $baseUrl = env('THINGSBOARD_URL'); $deviceId = $device->id; $keys = implode(',', $keyNames); $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json' ])->get("$baseUrl/api/plugins/telemetry/DEVICE/58bf81a0-0619-11f0-a9dc-45dd276e4cd5/values/timeseries", [ // ])->get("$baseUrl/api/plugins/telemetry/DEVICE/{$deviceId}/values/timeseries", [ 'keys' => $keys, // 'keys' => 'MechanicalHealth_valueInPercent', 'startTs' => $startTs, 'interval' => $endTs, 'limit' => 100, 'useStrictDataTypes' => false ]); // dd($response); // Check if the response was successful if (!$response->successful()) { Log::error("Failed to fetch telemetry for device: {$device->name} (ID: {$deviceId})", [ 'http_code' => $response->status(), 'url' => $response->effectiveUri(), 'response' => $response->body() ]); return ['error' => "Failed to fetch telemetry. HTTP Code: " . $response->status()]; } // Decode the telemetry response $telemetry = $response->json(); if (json_last_error() !== JSON_ERROR_NONE) { Log::error("Failed to decode telemetry response for device: {$device->name}", [ 'response' => $response->body() ]); return ['error' => 'Invalid telemetry response format']; } return $telemetry; } public function filterAlarm(array $data) { $token = $this->getToken(); $deviceId = null; if (!empty($data['deviceId'])) { $deviceId = $data['deviceId']; } elseif (!empty($data['assetId'])) { $deviceId = Device::where('asset_id', $data['assetId'])->value('id'); } if (!empty($data['assetId']) && empty($deviceId)) { return [ 'data' => [], 'totalPages' => 0, 'totalElements' => 0, 'hasNext' => false, ]; } $queryParams = array_filter([ 'severityList' => $data['severity'] ?? null, 'assigneeId' => $data['assignId'] ?? null, 'pageSize' => $data['pageSize'] ?? 10, 'page' => $data['page'] ?? 0, 'startTime' => $data['startTs'] ?? null, 'endTime' => $data['endTs'] ?? null, 'deviceId' => $deviceId, ], function ($value) { return $value !== null; }); $url = "{$this->baseUrl}/api/v2/alarms" . (count($queryParams) ? '?' . http_build_query($queryParams) : ''); $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', ])->get($url); if (!$response->successful()) { Log::error("API Error Response:", ['body' => $response->body()]); throw new Exception('API Error: ' . $response->body()); } $responseData = $response->json(); // If device filtering was applied, refine the results manually if (!empty($deviceId) && isset($responseData['data'])) { $filteredData = array_values(array_filter( $responseData['data'], function ($alarm) use ($deviceId) { return isset($alarm['originator']['id']) && $alarm['originator']['id'] === $deviceId; } )); // Update response with the filtered data $responseData['data'] = $filteredData; $responseData['totalElements'] = count($filteredData); } return $responseData; } public function createOrUpdateAlarm(array $data) { $token = $this->getToken(); $payload = [ 'type' => $data['type'] ?? null, 'severity' => $data['severity'] ?? null, 'acknowledged' => false, 'cleared' => $data['cleared'] ?? Carbon::now()->timestamp, 'startTs' => $data['startTs'] ?? Carbon::now()->timestamp, 'endTs' => $data['endTs'] ?? Carbon::now()->timestamp, 'originator' => [ 'id' => $data['originator'] ?? null, 'entityType' => 'DEVICE' ], // 'assigneeId' => [ // 'id' => $data['assigneeId'] ?? null, // 'entityType' => 'USER' // ], 'details' => $data['details'] ?? [], 'propagate' => $data['propagate'] ?? false, 'propagateToOwner' => $data['propagateToOwner'] ?? false, ]; // Optional fields if (!empty($data['id'])) { $payload['id'] = [ 'id' => $data['id'], 'entityType' => 'ALARM' ]; } $url = "{$this->baseUrl}/api/alarm"; $method = 'post'; $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', 'Content-Type' => 'application/json', ])->post($url, $payload); if (!$response->successful()) { Log::error("API Error Response:", ['body' => $response->body()]); throw new Exception('API Error: ' . $response->body()); } $apiResponse = $response->json(); return $apiResponse; } // public function deleteDevice(array $data) // { // $token = $this->getToken(); // $url = "{$this->baseUrl}/api/device/{$data['deviceId']}"; // $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' => 'Device deleted successfully']; // } // if ($response->successful()) { // return $response->json(); // } else { // throw new Exception('Failed to create Device: ' . $response->body()); // Log::info('API Response:', ['response' => $response]); // } // throw new Exception('Failed to create user: ' . $response->body()); // } }