From b15beaf7d0837888a3d077dcea216a5b94601e3b Mon Sep 17 00:00:00 2001 From: Shailesh-1981 <86923815+Shailesh-1981@users.noreply.github.com> Date: Wed, 26 Mar 2025 17:14:34 +0530 Subject: [PATCH 1/4] AlarmFetch --- .../APIS/AdminApi/AlarmController.php | 144 +++++++++ app/Services/AlarmService.php | 282 ++++++++++++++++++ routes/admin_api.php | 7 +- 3 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/APIS/AdminApi/AlarmController.php create mode 100644 app/Services/AlarmService.php diff --git a/app/Http/Controllers/APIS/AdminApi/AlarmController.php b/app/Http/Controllers/APIS/AdminApi/AlarmController.php new file mode 100644 index 0000000..bffd7c1 --- /dev/null +++ b/app/Http/Controllers/APIS/AdminApi/AlarmController.php @@ -0,0 +1,144 @@ +adminService = $adminService; + } + + + public function fetchAlarm(Request $request) + { + try { + // Get parameters from request + $severityList = $request->query('severityList', []); + $startTime = $request->query('startTime', null); + $endTime = $request->query('endTime', null); + + // Convert string to array if severityList is a single value + if (!is_array($severityList)) { + $severityList = explode(',', $severityList); + } + + // Debugging: Check received parameters + Log::info("Fetching alarms with severityList: " . implode(', ', $severityList) . + ", startTime: $startTime, endTime: $endTime"); + + // Get token for authentication + $token = $this->adminService->getToken(); + if (!$token) { + Log::error("Failed to authenticate with ThingsBoard."); + return response()->json(['error' => 'Authentication failed'], 401); + } + + // Build API URL with required parameters + $url = "http://65.0.131.117:8080/api/v2/alarms?pageSize=10&page=0"; + + // Append severityList if provided + if (!empty($severityList)) { + foreach ($severityList as $severity) { + $url .= "&severityList=" . urlencode($severity); + } + } + + // Append startTime and endTime if provided + if (!empty($startTime)) { + $url .= "&startTime=" . urlencode($startTime); + } + if (!empty($endTime)) { + $url .= "&endTime=" . urlencode($endTime); + } + + Log::info("Final API URL: " . $url); // Debugging + + // Make API request + $response = Http::withHeaders([ + 'Authorization' => "Bearer $token", + 'Accept' => 'application/json', + ])->get($url); + + if (!$response->successful()) { + Log::error("Failed to fetch ThingsBoard alarms: " . $response->body()); + return response()->json(['error' => 'Failed to fetch alarms'], 500); + } + + // Return filtered data + return response()->json(['alarmResponse' => $response->json()['data'] ?? []]); + + } catch (\Exception $e) { + Log::error("Error fetching ThingsBoard alarms: " . $e->getMessage()); + return response()->json(['error' => 'Server error'], 500); + } + } + + public function acknowledgeAlarm(Request $request) + { + try { + // Get alarmId from request + $alarmId = $request->input('alarmId'); + dd($alarmId); + + // Validate alarmId + if (!$alarmId) { + return response()->json(['error' => 'alarmId is required'], 400); + } + + // Debugging: Log received alarm ID + Log::info("Acknowledging alarm with ID: $alarmId"); + + // Get token for authentication + $token = $this->adminService->getToken(); + if (!$token) { + Log::error("Failed to authenticate with ThingsBoard."); + return response()->json(['error' => 'Authentication failed'], 401); + } + + // Build API URL using alarmId from request + $url = "http://65.0.131.117:8080/api/v2/alarm/{$alarmId}/ack?alarmId={$alarmId}"; + + Log::info("Final API URL: " . $url); // Debugging + + // Make API request + $response = Http::withHeaders([ + 'Authorization' => "Bearer $token", + 'Accept' => 'application/json', + ])->post($url); + + if (!$response->successful()) { + Log::error("Failed to acknowledge ThingsBoard alarm: " . $response->body()); + return response()->json(['error' => 'Failed to acknowledge alarm'], 500); + } + + // Return success response + return response()->json([ + 'message' => 'Alarm acknowledged successfully', + 'alarmId' => $alarmId + ]); + + } catch (\Exception $e) { + Log::error("Error acknowledging ThingsBoard alarm: " . $e->getMessage()); + return response()->json(['error' => 'Server error'], 500); + } + } + + + + + +} diff --git a/app/Services/AlarmService.php b/app/Services/AlarmService.php new file mode 100644 index 0000000..3499702 --- /dev/null +++ b/app/Services/AlarmService.php @@ -0,0 +1,282 @@ +adminService = $adminService; + } + + 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; + } + + + + + + + + + +} diff --git a/routes/admin_api.php b/routes/admin_api.php index 8292c3a..4120514 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -1,13 +1,14 @@ name('user_list'); Route::delete('/users-delete/{userId}', [UsersController::class, 'delete']); Route::post('/activate/{id}', [UsersController::class, 'activate'])->name('activate.user'); Route::post('/users-login', [UsersController::class, 'loginUser']); + +// ****************************************************** Alarm Fetch *************************** +Route::post('/alarm-fetch', [AlarmController::class, 'fetchAlarm'])->name('alarm_fetch'); +Route::post('/acknowledge-alarm',[AlarmController::class, 'acknowledgeAlarm'])->name('acknowledge_alarm'); From c4d43bbf42d2497daa8dc525d013b9ea3ed9598a Mon Sep 17 00:00:00 2001 From: Shailesh-1981 <86923815+Shailesh-1981@users.noreply.github.com> Date: Thu, 27 Mar 2025 12:03:40 +0530 Subject: [PATCH 2/4] pull from main --- routes/admin_api.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/admin_api.php b/routes/admin_api.php index b19b6e5..127e2be 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -44,6 +44,6 @@ Route::delete('/users-delete/{userId}', [UsersController::class, 'delete']); Route::post('/activate/{id}', [UsersController::class, 'activate'])->name('activate.user'); Route::post('/users-login', [UsersController::class, 'loginUser']); -// ****************************************************** Alarm Fetch *************************** -Route::post('/alarm-fetch', [AlarmController::class, 'fetchAlarm'])->name('alarm_fetch'); -Route::post('/acknowledge-alarm',[AlarmController::class, 'acknowledgeAlarm'])->name('acknowledge_alarm'); +// // ****************************************************** Alarm Fetch *************************** +// Route::post('/alarm-fetch', [AlarmController::class, 'fetchAlarm'])->name('alarm_fetch'); +// Route::post('/acknowledge-alarm',[AlarmController::class, 'acknowledgeAlarm'])->name('acknowledge_alarm'); From e1d502fc3807c5eb8d368c5bd907c1e2282e1e12 Mon Sep 17 00:00:00 2001 From: sayaliparab Date: Thu, 27 Mar 2025 15:26:26 +0530 Subject: [PATCH 3/4] assest validation --- app/Http/Requests/CreateAssetRequest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Requests/CreateAssetRequest.php b/app/Http/Requests/CreateAssetRequest.php index d6e642e..acacbb7 100644 --- a/app/Http/Requests/CreateAssetRequest.php +++ b/app/Http/Requests/CreateAssetRequest.php @@ -22,18 +22,18 @@ class CreateAssetRequest extends FormRequest public function rules(): array { return [ - 'id' => 'required|uuid', + // 'id' => 'required|uuid', 'entity_type' => 'required|string|in:ASSET', 'created_time' => 'required|integer', - 'tenant_id' => 'required|uuid', + // 'tenant_id' => 'required|uuid', 'customer_xid' => 'required|uuid', 'name' => 'required|string|max:255', 'type' => 'required|string|max:255', 'label' => 'nullable|string|max:255', - 'asset_profile_id' => 'required|uuid', + // 'asset_profile_id' => 'required|uuid', 'external_id' => 'nullable|uuid', 'version' => 'nullable|integer|min:1', - 'additional_info' => 'nullable|json', + // 'additional_info' => 'nullable|json', ]; } } From b54c6dbfba9caf46bed4028cab3079c8a1674e0c Mon Sep 17 00:00:00 2001 From: Shailesh-1981 <86923815+Shailesh-1981@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:20:57 +0530 Subject: [PATCH 4/4] api create --- .../APIS/CustomerApi/DownloadsController.php | 94 +++++++++++++++++++ app/Models/Reports.php | 16 ++++ ...2025_03_27_064213_create_reports_table.php | 34 +++++++ ...27_073243_add_user_id_to_reports_table.php | 32 +++++++ routes/admin_api.php | 2 + routes/customer_api.php | 14 ++- 6 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 app/Http/Controllers/APIS/CustomerApi/DownloadsController.php create mode 100644 app/Models/Reports.php create mode 100644 database/migrations/2025_03_27_064213_create_reports_table.php create mode 100644 database/migrations/2025_03_27_073243_add_user_id_to_reports_table.php diff --git a/app/Http/Controllers/APIS/CustomerApi/DownloadsController.php b/app/Http/Controllers/APIS/CustomerApi/DownloadsController.php new file mode 100644 index 0000000..e8d0f71 --- /dev/null +++ b/app/Http/Controllers/APIS/CustomerApi/DownloadsController.php @@ -0,0 +1,94 @@ +all(), [ + 'user_id' => ['required'], + 'device_xid' => ['required'], + 'start_date' => ['required'], + 'end_date' => ['required'], + 'report_type' => ['required'], + 'download_status' => ['required'], + ]); + if ($validator->fails()) { + return response()->json([ + 'status' => 422, + 'message' => 'Validation failed', + 'errors' => $validator->errors() + ]); + } + + $data = Reports::create([ + 'request_time' => Carbon::now(), + 'user_id' => $request->user_id, + 'device_xid' => $request->device_xid, + 'start_date' => $request->start_date, + 'end_date' => $request->end_date, + 'report_type' => $request->report_type, + 'download_status' => $request->download_status, + ]); + + if ($data) { + return response()->json([ + 'status' => 200, + 'message' => 'Report data saved successfully', + 'data' => $data + ]); + } + } + + public function fetchReport(Request $request) + { + $userId = Auth::id(); + $data = Reports::where('user_id', $userId)->whereNull('deleted_at')->get(); + if($data){ + return response()->json([ + 'status' => 200, + 'message' => 'Report data fetch successfully', + 'data' => $data + ]); + + }else{ + return response()->json([ + 'status' => 404, + 'message' => 'Report data not found', + 'data' => $data + ]); + + } + + } + + public function destroyReport() + { + $userId = Auth::id(); + $data = Reports::where('user_id', $userId)->whereNull('deleted_at')->delete(); + if ($data) { + return response()->json([ + 'status' => 200, + 'message' => 'Report data deleted successfully', + 'data' => $data + ]); + } else { + return response()->json([ + 'status' => 404, + 'message' => 'Report data not found', + 'data' => $data + ]); + } + } +} diff --git a/app/Models/Reports.php b/app/Models/Reports.php new file mode 100644 index 0000000..45af36f --- /dev/null +++ b/app/Models/Reports.php @@ -0,0 +1,16 @@ +id(); + $table->timestamp('request_time')->nullable();; + $table->string('device_xid'); + $table->timestamp('start_date')->nullable();; + $table->timestamp('end_date')->nullable();; + $table->boolean('report_type')->default(false)->comment('Report status: 0 = pdf, 1 = spreadsheet'); + $table->boolean('download_status')->default(false)->comment('Download status: 0 = failed, 1 = completed'); + $table->softDeletes(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('reports'); + } +}; diff --git a/database/migrations/2025_03_27_073243_add_user_id_to_reports_table.php b/database/migrations/2025_03_27_073243_add_user_id_to_reports_table.php new file mode 100644 index 0000000..5749b07 --- /dev/null +++ b/database/migrations/2025_03_27_073243_add_user_id_to_reports_table.php @@ -0,0 +1,32 @@ +string('user_id')->nullable()->after('request_time'); // Change 'existing_column' to the column after which you want to add the new column + + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('reports', function (Blueprint $table) { + // + $table->dropColumn('user_id'); + + }); + } +}; diff --git a/routes/admin_api.php b/routes/admin_api.php index ec53649..0745cd8 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -64,3 +64,5 @@ Route::post('/update-device-profile-master/{deviceId}', [DeviceProfileMasterCont Route::post('/alarm/create-or-update', [AlarmController::class, 'createOrUpdateAlarm'])->name('alarm.create-or-update'); Route::post('/alarm/filter', [AlarmController::class, 'filterAlarm'])->name('alarm.filter'); +//******************************************************* Report API ******************************************************** + diff --git a/routes/customer_api.php b/routes/customer_api.php index a6bbd57..223b9a3 100644 --- a/routes/customer_api.php +++ b/routes/customer_api.php @@ -8,6 +8,8 @@ use Tymon\JWTAuth\Facades\JWTAuth; use App\Http\Controllers\APIS\CustomerApi\AuthController; use App\Http\Controllers\APIS\CustomerApi\CustomerDeviceInfoController; use App\Http\Controllers\APIS\CustomerApi\TelemetryController; +use App\Http\Controllers\APIS\CustomerApi\DownloadsController as CustomerApiDownloadsController; + Route::get('/customerapi', function () { return ('Welcome to admin api routes.'); @@ -15,15 +17,17 @@ Route::get('/customerapi', function () { Route::post('user-login', [AuthController::class, 'login']); -Route::get('/customer-device-info',[CustomerDeviceInfoController::class,'customerDeviceInfo']); -Route::post('/telemetry-data-asset',[TelemetryController::class,'telemetryDataAsset']); -Route::post('/telemetry-data-device',[TelemetryController::class,'telemetryDataDevice']); -Route::post('/telemetry-data-device-diagnostic',[TelemetryController::class,'telemePtryDataDeviceDiagnostic']); +Route::get('/customer-device-info', [CustomerDeviceInfoController::class, 'customerDeviceInfo']); +Route::post('/telemetry-data-asset', [TelemetryController::class, 'telemetryDataAsset']); +Route::post('/telemetry-data-device', [TelemetryController::class, 'telemetryDataDevice']); +Route::post('/telemetry-data-device-diagnostic', [TelemetryController::class, 'telemePtryDataDeviceDiagnostic']); // Route::post('/user-login', [AuthController::class, 'login']); Route::middleware(['customerApiBasicAuth'])->group(function () { Route::get('/user-assets', [UserAssetLinkController::class, 'index']); - + Route::post('/store/report', [CustomerApiDownloadsController::class, 'storePdfData'])->name('store-report'); + Route::post('/fetch/report', [CustomerApiDownloadsController::class, 'fetchReport'])->name('fetch-report'); + Route::post('/destroy/report', [CustomerApiDownloadsController::class, 'destroyReport'])->name('destroy-report'); });