customerInfoService = $customerInfoService; // } public function __construct(CustomerInfoService $customerInfoService, AlarmService $alarmService, AdminService $adminService, TelemetryService $telemetryService) { $this->customerInfoService = $customerInfoService; $this->alarmService = $alarmService; $this->adminService = $adminService; $this->telemetryService = $telemetryService; } // public function telemetryDataAsset(Request $request) // { // try { // $token = readHeaderToken(); // $userId = $token['sub']; // $customerId = User::where('id', $userId)->value('customer_id'); // // Validate request // $validator = Validator::make($request->all(), [ // 'asset_id' => 'required|string', // ]); // if ($validator->fails()) { // return jsonResponseWithErrorMessage($validator->errors()->first(), 400); // } // $assetId = $request->input('asset_id'); // // Verify asset ownership // $assetLinkExists = UserAssetLink::where('user_id', $userId) // ->where('asset_id', $assetId) // ->exists(); // if (!$assetLinkExists) { // return response()->json([ // 'error' => 'You are not authorized to access this asset', // 'code' => 'UNAUTHORIZED_ACCESS' // ], 403); // } // // Set timestamps in milliseconds for database query // $endTsMs = now()->timestamp * 1000; // Current time in milliseconds // $startTsMs = $endTsMs - (30 * 60 * 1000); // 30 minutes ago in milliseconds // // Get devices with their telemetry keys // $devices = Device::with([ // 'deviceProfile' => function($query) { // $query->select(['id', 'name']); // Only select needed fields // }, // 'timeseriesKeys' => function ($query) { // $query->where('display_on_dashboard', true) // ->orWhere('display_on_popup', true) // ->select(['id', 'device_profile_xid', 'key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); // } // ])->where('asset_id', $assetId) // ->where('customer_id', $customerId) // ->get(); // if ($devices->isEmpty()) { // return response()->json([ // 'error' => 'No devices found for the specified asset', // 'code' => 'DEVICES_NOT_FOUND' // ], 404); // } // // Process telemetry data for each device // $response = $devices->map(function ($device) use ($startTsMs, $endTsMs) { // $keysData = $device->timeseriesKeys; // $keyNames = $keysData->pluck('key_name')->toArray(); // // Get telemetry data for start and end times // $startTelemetry = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTsMs, $startTsMs); // $endTelemetry = $this->customerInfoService->getTelemetryData($device, $keyNames, $endTsMs, $endTsMs); // $alarmMap = $this->getDeviceAlarmsForTelemetry($device->id); // $alertMessages = TimeseriesAlertMessage::whereIn('timeseries_key_master_xid', $keysData->pluck('id')) // ->orderBy('min_value', 'asc') // ->get() // ->groupBy('timeseries_key_master_xid'); // $telemetry = $keysData->map(function ($keyData) use ($startTelemetry, $endTelemetry, $alarmMap, $alertMessages) { // $startData = collect($startTelemetry[$keyData->key_name] ?? [])->last(); // $endData = collect($endTelemetry[$keyData->key_name] ?? [])->last(); // $startValue = floatval($startData['value'] ?? 0); // $endValue = floatval($endData['value'] ?? 0); // // Determine trend // $trend = null; // if ($startValue > 0) { // if ($endValue > $startValue) { // $trend = 'upward'; // } elseif ($endValue < $startValue) { // $trend = 'downward'; // } else { // $trend = 'stable'; // } // } // // Format timestamp // $currentData = $endData ?? $startData ?? ['ts' => now()->timestamp * 1000]; // $timestamp = is_float($currentData['ts']) || $currentData['ts'] > 9999999999 // ? intval($currentData['ts'] / 1000) // : $currentData['ts']; // // Color code logic // $colorCode = null; // if ($endValue == 0) { // $colorCode = "grey"; // } elseif (isset($alertMessages[$keyData->id])) { // foreach ($alertMessages[$keyData->id] as $alertMsg) { // if ((is_null($alertMsg->min_value) || $endValue >= floatval($alertMsg->min_value)) && // (is_null($alertMsg->max_value) || $endValue <= floatval($alertMsg->max_value))) { // $colorCode = $alertMsg->color_code; // break; // } // } // } // return [ // 'key_name' => $keyData->key_name, // 'display_name' => $keyData->display_name, // 'display_on_dashboard' => $keyData->display_on_dashboard, // 'display_on_popup' => $keyData->display_on_popup, // 'timestamp' => $timestamp, // 'value' => $endValue, // 'start_value' => $startValue > 0 ? $startValue : null, // 'trend' => $trend, // 'alert' => isset($alarmMap[$keyData->key_name]), // 'color_code' => $colorCode ?: 'green', // Default to green if no alerts match // ]; // })->filter()->values(); // return [ // 'device_id' => (string) $device->id, // 'device_profile_name' => (string) $device->deviceProfile->name, // 'asset_id' => (string) $device->asset_id, // 'device_profile_id' => (string) $device->device_profile_id, // 'telemetry' => $telemetry, // ]; // }); // return response()->json([ // 'telemetry' => $response, // 'time_range' => [ // 'startTs' => intval($startTsMs / 1000), // 'endTs' => intval($endTsMs / 1000), // ] // ]); // } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { // return response()->json([ // 'error' => 'User not found', // 'code' => 'USER_NOT_FOUND' // ], 404); // } catch (\Exception $e) { // Log::error('Telemetry data fetch failed: ' . $e->getMessage(), [ // 'exception' => $e, // 'user_id' => $userId ?? null, // 'asset_id' => $assetId ?? null // ]); // return response()->json([ // 'error' => 'Failed to fetch telemetry data', // 'code' => 'SERVER_ERROR' // ], 500); // } // } public function telemetryDataAsset(Request $request) { try { $token = readHeaderToken(); $userId = $token['sub']; $customerId = User::where('id', $userId)->value('customer_id'); $validator = Validator::make($request->all(), [ 'asset_id' => 'required|string', ]); if ($validator->fails()) { return jsonResponseWithErrorMessage($validator->errors()->first(), 400); } $assetId = $request->input('asset_id'); if (!$this->validateAssetAccess($userId, $assetId)) { return response()->json([ 'error' => 'You are not authorized to access this asset', 'code' => 'UNAUTHORIZED_ACCESS' ], 403); } $endTsMs = now()->timestamp * 1000; $startTsMs = $endTsMs - (30 * 60 * 1000); $devices = $this->getDevicesForAsset($assetId, $customerId); if ($devices->isEmpty()) { return response()->json([ 'error' => 'No devices found for the specified asset', 'code' => 'DEVICES_NOT_FOUND' ], 404); } $response = $this->processDevicesTelemetry($devices, $startTsMs, $endTsMs); return response()->json([ 'telemetry' => $response, 'time_range' => [ 'startTs' => intval($startTsMs / 1000), 'endTs' => intval($endTsMs / 1000), ] ]); } catch (\Exception $e) { Log::error('Telemetry data fetch failed: ' . $e->getMessage()); return response()->json([ 'error' => 'Failed to fetch telemetry data', 'code' => 'SERVER_ERROR' ], 500); } } private function validateAssetAccess($userId, $assetId): bool { return UserAssetLink::where('user_id', $userId) ->where('asset_id', $assetId) ->exists(); } private function getDevicesForAsset($assetId, $customerId) { return Device::with([ 'deviceProfile:id,name', 'timeseriesKeys' => function ($query) { $query->where('display_on_dashboard', true) ->orWhere('display_on_popup', true) ->select(['id', 'device_profile_xid', 'key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); } ])->where('asset_id', $assetId) ->where('customer_id', $customerId) ->get(); } private function processDevicesTelemetry($devices, $startTsMs, $endTsMs) { return $devices->map(function ($device) use ($startTsMs, $endTsMs) { $isActive = $this->checkDeviceActiveStatus($device); $keysData = $device->timeseriesKeys; $keyNames = $keysData->pluck('key_name')->toArray(); $startTelemetry = []; $endTelemetry = []; if ($isActive) { $startTelemetry = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTsMs, $startTsMs); $endTelemetry = $this->customerInfoService->getTelemetryData($device, $keyNames, $endTsMs, $endTsMs); } $alarmMap = $this->getDeviceAlarmsForTelemetry($device->id); $alertMessages = $this->getAlertMessages($keysData); $telemetry = $this->processTelemetryData($keysData, $startTelemetry, $endTelemetry, $alarmMap, $alertMessages, $isActive); return [ 'device_id' => (string) $device->id, 'device_name' => (string) $device->deviceProfile->name, 'device_profile_name' => (string) $device->deviceProfile->name, 'asset_id' => (string) $device->asset_id, 'device_profile_id' => (string) $device->device_profile_id, 'is_active' => $isActive, 'telemetry' => $telemetry, ]; }); } private function checkDeviceActiveStatus($device): bool { $deviceInfoToken = $this->adminService->getToken(); if (!$deviceInfoToken) { return false; } $baseUrl = env('THINGSBOARD_URL'); $deviceInfoResponse = Http::withHeaders([ 'Authorization' => "Bearer $deviceInfoToken", 'Accept' => 'application/json', ])->get("{$baseUrl}api/device/info/{$device->id}"); if ($deviceInfoResponse->successful()) { $deviceInfo = $deviceInfoResponse->json(); return $deviceInfo['active'] ?? false; } Log::error("Failed to fetch device info for device ID: {$device->id}"); return false; } private function getAlertMessages($keysData) { return TimeseriesAlertMessage::whereIn('timeseries_key_master_xid', $keysData->pluck('id')) ->orderBy('min_value', 'asc') ->get() ->groupBy('timeseries_key_master_xid'); } private function processTelemetryData($keysData, $startTelemetry, $endTelemetry, $alarmMap, $alertMessages, $isActive) { return $keysData->map(function ($keyData) use ($startTelemetry, $endTelemetry, $alarmMap, $alertMessages, $isActive) { $startValue = 0; $endValue = 0; $timestamp = now()->timestamp; $trend = null; if ($isActive) { $startData = collect($startTelemetry[$keyData->key_name] ?? [])->last(); $endData = collect($endTelemetry[$keyData->key_name] ?? [])->last(); $startValue = floatval($startData['value'] ?? 0); $endValue = floatval($endData['value'] ?? 0); if ($startValue > 0) { $trend = $this->determineTrend($endValue, $startValue); } $currentData = $endData ?? $startData ?? ['ts' => now()->timestamp * 1000]; $timestamp = $this->formatTimestamp($currentData['ts']); } $colorCode = $this->determineColorCode($endValue, $alertMessages, $keyData->id, $isActive); return [ 'key_name' => $keyData->key_name, 'display_name' => $keyData->display_name, 'display_on_dashboard' => $keyData->display_on_dashboard, 'display_on_popup' => $keyData->display_on_popup, 'timestamp' => $timestamp, 'value' => $isActive ? $endValue : 0, 'start_value' => $isActive && $startValue > 0 ? $startValue : null, 'trend' => $trend, 'alert' => isset($alarmMap[$keyData->key_name]), 'color_code' => $colorCode, ]; })->filter()->values(); } private function determineTrend($endValue, $startValue): ?string { if ($endValue > $startValue) { return 'upward'; } elseif ($endValue < $startValue) { return 'downward'; } return 'stable'; } private function formatTimestamp($ts): int { return is_float($ts) || $ts > 9999999999 ? intval($ts / 1000) : $ts; } private function determineColorCode($endValue, $alertMessages, $keyId, $isActive): string { if (!$isActive) { return 'grey'; } if ($endValue == 0) { return 'grey'; } if (isset($alertMessages[$keyId])) { foreach ($alertMessages[$keyId] as $alertMsg) { if ((is_null($alertMsg->min_value) || $endValue >= floatval($alertMsg->min_value)) && (is_null($alertMsg->max_value) || $endValue <= floatval($alertMsg->max_value))) { return $alertMsg->color_code; } } } return 'green'; } private function getDeviceAlarmsForTelemetry($deviceId) { Log::info("Fetching alarms for device: {$deviceId}"); $pageSize = 1000; $page = 0; // Fetch ThingsBoard token $token = $this->alarmService->getToken(); if (!$token) { Log::error("Failed to fetch ThingsBoard token."); return []; } Log::info("Token fetched successfully."); $baseUrl = env('THINGSBOARD_URL'); $endTime = now()->timestamp * 1000; // Current time in ms $startTime = now()->subHours(24)->timestamp * 1000; // 24 hours ago in ms Log::info("Time range: Start => {$startTime}, End => {$endTime}"); // Fetch alarms from ThingsBoard API try { $response = Http::withHeaders([ 'Authorization' => "Bearer $token", 'Accept' => 'application/json', ])->get("{$baseUrl}api/v2/alarms", [ 'statusList' => 'ACTIVE', 'severityList' => 'CRITICAL,MAJOR,MINOR,WARNING', 'pageSize' => $pageSize, 'page' => $page, 'startTime' => $startTime, 'endTime' => $endTime, 'sortProperty' => 'createdTime', 'sortOrder' => 'DESC', 'originator' => $deviceId // Filter by device ID ]); if (!$response->successful()) { Log::error("Failed to fetch alarms. Status: " . $response->status()); return []; } // Parse the response $alarms = $response->json()['data'] ?? []; Log::info("Fetched " . count($alarms) . " alarms for device ID: {$deviceId}"); // Map alarms by `type` field $alarmMap = []; foreach ($alarms as $alarm) { if (isset($alarm['type'])) { $alarmMap[$alarm['type']] = true; } } Log::info("Mapped alarm types: ", $alarmMap); return $alarmMap; } catch (\Exception $e) { Log::error("Error fetching alarms: " . $e->getMessage()); return []; } } // public function telemetryDataDevice(Request $request) // { // try { // $token = readHeaderToken(); // if (!$token) { // return response()->json([ // 'success' => false, // 'error' => 'Authorization token required' // ], 401); // } // $validator = Validator::make($request->all(), [ // 'device_id' => 'required|string', // 'startTs' => 'nullable|string', // 'endTs' => 'nullable|string', // ]); // if ($validator->fails()) { // return response()->json([ // 'success' => false, // 'error' => $validator->errors()->first() // ], 400); // } // $deviceId = $request->input('device_id'); // $startTs = $request->input('startTs') ?: null; // $endTs = $request->input('endTs') ?: null; // try { // $deviceWithTelemetry = Device::with([ // 'deviceProfile', // 'timeseriesKeys' => function ($query) { // $query->select('key_name', 'display_name', 'device_profile_xid', 'display_on_dashboard','display_on_dashboard'); // } // ]) // ->where('id', $deviceId) // ->firstOrFail(); // $telemetryResponse = $this->customerInfoService->getTelemetryDataDevice( // $deviceWithTelemetry, // $deviceWithTelemetry->timeseriesKeys->pluck('key_name')->toArray(), // $startTs, // $endTs, // $token // ); // if (!is_array($telemetryResponse)) { // throw new \Exception("Invalid telemetry data format received from service"); // } // $telemetry = collect($telemetryResponse) // ->flatMap(function ($items, $keyName) use ($deviceWithTelemetry) { // $displayName = $deviceWithTelemetry->timeseriesKeys // ->firstWhere('key_name', $keyName)?->display_name ?? $keyName; // return collect($items)->map(function ($item) use ($keyName, $displayName) { // return [ // 'key_name' => $keyName, // 'timestamp' => $item['ts'] ?? null, // 'value' => $item['value'] ?? null, // 'display_name' => $displayName, // 'display_on_dashboard' // ]; // }); // }) // ->values() // ->all(); // return response()->json([ // 'success' => true, // 'telemetry' => [ // 'device_id' => (string) $deviceWithTelemetry->id, // 'device_name' => $deviceWithTelemetry->name, // 'device_profile_name' => $deviceWithTelemetry->deviceProfile->name, // 'device_profile_id' => (string) $deviceWithTelemetry->device_profile_id, // 'telemetry_data' => $telemetry, // ] // ], 200); // } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { // return response()->json([ // 'success' => false, // 'error' => 'Device not found' // ], 404); // } catch (\Exception $e) { // return response()->json([ // 'success' => false, // 'error' => 'Failed to fetch telemetry data', // 'details' => config('app.debug') ? $e->getMessage() : null // ], 503); // } // } catch (\Exception $e) { // return response()->json([ // 'success' => false, // 'error' => 'Internal server error', // 'details' => config('app.debug') ? $e->getMessage() : null // ], 500); // } // } public function telemetryDataDevice(Request $request) { try { $token = readHeaderToken(); $customerId = User::where('id', $token['sub'])->value('customer_id'); Log::info('Telemetry request received', ['request_data' => $request->all()]); if (!$token) { Log::warning('Unauthorized access attempt: Missing token'); return response()->json([ 'success' => false, 'error' => 'Authorization token required' ], 401); } $validator = Validator::make($request->all(), [ 'device_id' => 'required|string', 'startTs' => 'nullable|string', 'endTs' => 'nullable|string', ]); if ($validator->fails()) { Log::error('Validation failed', ['errors' => $validator->errors()]); return response()->json([ 'success' => false, 'error' => $validator->errors()->first() ], 400); } $deviceId = $request->input('device_id'); $startTs = $request->input('startTs') ?: null; $endTs = $request->input('endTs') ?: null; $device = $this->getDeviceWithTelemetryKeys($deviceId, $customerId); $displayKeys = $device->timeseriesKeys->pluck('key_name')->toArray(); $deviceProfileName = strtolower($device->deviceProfile->name ?? ''); Log::info('Device profile and keys retrieved', [ 'device_profile' => $deviceProfileName, 'display_keys' => $displayKeys ]); // Check pressure value for specific device profiles $pressureActive = $this->checkPressureValue( $device, $deviceProfileName, $displayKeys, $startTs, $endTs ); $telemetryResponse = $this->customerInfoService->getTelemetryDataDevice( $device, $displayKeys, $startTs, $endTs, $token ); if (!is_array($telemetryResponse)) { Log::error('Invalid telemetry data format received'); throw new \Exception("Invalid telemetry data format received from service"); } $filteredResponse = $this->filterTelemetryResponse($telemetryResponse, $displayKeys, $pressureActive); $telemetry = $this->formatDeviceTelemetry($filteredResponse, $device); Log::info('Telemetry response successfully generated', ['device_id' => $deviceId]); return response()->json([ 'success' => true, 'telemetry' => [ 'device_id' => (string) $device->id, 'device_name' => $device->name, 'device_profile_name' => $device->deviceProfile->name, 'device_profile_id' => (string) $device->device_profile_id, 'pressure_value' => $pressureActive, 'telemetry_data' => $telemetry, ] ], 200); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { Log::error('Device not found', ['device_id' => $deviceId ?? null]); return response()->json([ 'success' => false, 'error' => 'Device not found' ], 404); } catch (\Exception $e) { Log::critical('Internal server error', ['error' => $e->getMessage()]); return response()->json([ 'success' => false, 'error' => 'Internal server error', 'details' => config('app.debug') ? $e->getMessage() : null ], 500); } } private function getDeviceWithTelemetryKeys($deviceId, $customerId) { return Device::with([ 'deviceProfile', 'timeseriesKeys' => function ($query) { $query->where(function ($q) { $q->where('display_on_dashboard', true) ->orWhere('display_on_popup', true); }) ->select('key_name', 'display_name', 'device_profile_xid', 'display_on_dashboard', 'display_on_popup'); } ]) ->where('id', $deviceId) ->where('customer_id', $customerId) ->firstOrFail(); } private function checkPressureValue($device, $deviceProfileName, $displayKeys, $startTs, $endTs) { $pressureKey = 'Pressure_value'; $pressureActive = false; // Check if the device has "Gas Engine Profile" or "Engine Profile" in its profile name if (strpos($deviceProfileName, 'gas engine profile') !== false || strpos($deviceProfileName, 'engine profile') !== false) { $token = readHeaderToken(); $pressureResponse = $this->customerInfoService->getTelemetryDataDevice( $device, [$pressureKey], $startTs, $endTs, $token ); if (isset($pressureResponse[$pressureKey]) && is_array($pressureResponse[$pressureKey])) { foreach ($pressureResponse[$pressureKey] as $pressureData) { if (!empty($pressureData['value']) && floatval($pressureData['value']) > 0) { $pressureActive = true; break; } } } } return $pressureActive; } private function filterTelemetryResponse($telemetryResponse, $displayKeys, $pressureActive) { // Filter telemetry data based on display keys $filteredResponse = array_intersect_key($telemetryResponse, array_flip($displayKeys)); // Add Pressure key if condition is met $pressureKey = 'Pressure_value'; if ($pressureActive && isset($telemetryResponse[$pressureKey])) { $filteredResponse[$pressureKey] = $telemetryResponse[$pressureKey]; } return $filteredResponse; } private function formatDeviceTelemetry($filteredResponse, $device) { return collect($filteredResponse) ->flatMap(function ($items, $keyName) use ($device) { $keyData = $device->timeseriesKeys->firstWhere('key_name', $keyName); return collect($items)->map(function ($item) use ($keyName, $keyData) { return [ 'key_name' => $keyName, 'timestamp' => $item['ts'] ?? null, 'value' => $item['value'] ?? null, 'display_name' => $keyData->display_name ?? $keyName, 'display_on_dashboard' => $keyData->display_on_dashboard ?? false, 'display_on_popup' => $keyData->display_on_popup ?? false ]; }); }) ->values() ->all(); } public function convertToUserTimezone($utcDatetime, $userTimezone = 'Asia/Kolkata', $format = 'd-M-Y H:i:s') { return Carbon::parse($utcDatetime, 'UTC') ->setTimezone($userTimezone) ->format($format); } public function entityQuery(){ try { $token = readHeaderToken(); // Retrieve devices of user $deviceIds = $this->getUserDeviceIds($token['sub']); // Retrieve required timeseries of devices $timeseriesKeys = $this->getAllDashboardTimeseriesKeys(); $entityQuery = $this->customerInfoService->fetchEntityQuery($deviceIds, $timeseriesKeys); // Ensure the response is converted to an array if it's a JsonResponse $data = $entityQuery instanceof \Illuminate\Http\JsonResponse ? $entityQuery->getData(true) : $entityQuery; $timeseriesKeyMap = $this->getTimeseriesKeysByProfile(); // Process the array and format the output $formatted = [ 'success' => true, 'data' => collect($data['data'])->map(function ($device) use ($timeseriesKeyMap) { $deviceType = $device['latest']['ENTITY_FIELD']['type']['value'] ?? null; $deviceProfileId = DeviceProfileMaster::where('name', $deviceType)->select('id')->first(); $allTimeseries = $device['latest']['TIME_SERIES'] ?? []; // Step 2: Get allowed keys for this device type $allowedKeys = $timeseriesKeyMap[$deviceProfileId['id']] ?? []; // Step 3: Filter timeseries to only include allowed keys $filteredTimeseries = collect($allTimeseries) ->only($allowedKeys) ->toArray(); return [ 'deviceId' => $device['entityId']['id'] ?? null, 'deviceName' => $device['latest']['ENTITY_FIELD']['name']['value'] ?? null, 'deviceProfileId' => $deviceProfileId['id'] ?? null, 'deviceType' => $deviceType, 'timeseries' => $filteredTimeseries, ]; })->toArray() ]; return response()->json($formatted); } catch(Exception $e){ return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } private function getUserDeviceIds($userId) { return UserAssetLink::with('asset.devices') ->where('user_id', $userId) ->get() ->pluck('asset.devices') ->flatten() ->pluck('id') ->toArray(); } private function getAllDashboardTimeseriesKeys() { return TimeseriesKeyMaster::where('display_on_dashboard', 1) ->orWhere('display_on_popup', 1) ->get() ->pluck('key_name') ->flatten() ->toArray(); } private function getTimeseriesKeysByProfile() { return TimeseriesKeyMaster::where('display_on_dashboard', 1) ->orWhere('display_on_popup', 1) ->get() ->groupBy('device_profile_xid') ->map(function ($group) { return $group->pluck('key_name')->toArray(); }); } public function userAssetsNew(){ try { $token = readHeaderToken(); $userId = $token['sub']; // Set cache key per user $cacheKey = "user_assets_health_{$userId}"; // Cache for 15 minutes // $formattedData = Cache::remember($cacheKey, now()->addMinutes(value: 15), function () use ($userId) { $assetDeviceListing = UserAssetLink::with('asset.devices') ->where(['user_id' => $userId, 'active' => 1]) ->get(); $formattedData = $assetDeviceListing->map(function ($link) { $asset = $link->asset; $deviceHealthStatuses = []; $devicesData = $asset->devices->map(function ($device) use (&$deviceHealthStatuses) { $telemetryValues = $this->getHealthConditionTelemetry($device); $deviceHealth = $this->telemetryService->getDeviceHealth($telemetryValues); $deviceHealthStatuses[] = $deviceHealth; return [ 'deviceId' => $device->id, 'deviceName' => $device->name, 'deviceHealth' => $deviceHealth ]; })->values(); return [ 'assetId' => $asset->id, 'assetName' => $asset->name, 'assetHealth' => $deviceHealthStatuses ? $this->telemetryService->getAssetHealth($deviceHealthStatuses) : null, 'devices' => $devicesData ]; }); // }); return response()->json(['success' => true, 'data' => $formattedData]); } catch(Exception $e){ return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } private function getHealthConditionTelemetry($device) { $timeseriesKeys = TimeseriesKeyMaster::where('display_on_health_condition', 1) ->where('device_profile_xid', $device->device_profile_id) ->pluck('key_name') ->implode(','); $telemetryValue = $this->customerInfoService->fetchTelemetryData($device->id, $timeseriesKeys); $data = $telemetryValue instanceof \Illuminate\Http\JsonResponse ? $telemetryValue->getData(true) : $telemetryValue; $transformedTelemetry = []; if (!empty($data) && is_array($data)) { foreach ($data as $key => $items) { foreach ($items as $item) { $transformedTelemetry[] = [ 'key_name' => $key, 'value' => $item['value'] ]; } } } return $transformedTelemetry; } public function customerDeviceInfoNew() { try { $token = readHeaderToken(); $cacheKey = 'device_info_' . $token['sub']; // Cache the entire response for 15 minutes // $response = Cache::remember($cacheKey, now()->addMinutes(value: 15), function () use ($token) { $devices = UserAssetLink::with('asset.devices') ->where(['user_id' => $token['sub'], 'active' => 1]) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $good = $moderate = $bad = 0; $deviceIds = $devices->pluck('id')->toArray(); if (!empty($deviceIds)) { foreach ($deviceIds as $deviceId) { $device = Device::find($deviceId); if ($device) { $telemetryValues = $this->getHealthConditionTelemetry($device); $deviceHealth = $this->telemetryService->getDeviceHealth($telemetryValues); match ($deviceHealth) { 'green' => $good++, 'orange' => $moderate++, default => $bad++ }; } } $deviceCount = $this->customerInfoService->getDevicesCount($deviceIds); $alarms = $this->customerInfoService->fetchDeviceAlarms($deviceIds); } $response = [ 'success' => true, 'good' => $good, 'moderate' => $moderate, 'bad' => $bad, 'total' => $deviceCount['totalDevices'] ?? 0, 'active' => $deviceCount['activeDevices'] ?? 0, 'alarm' => $alarms['count'] ?? 0 ]; // }); return response()->json($response); } catch (Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getActiveDevicesList(){ try { $token = readHeaderToken(); $devices = UserAssetLink::with('asset.devices') ->where(['user_id' => $token['sub'], 'active' => 1]) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $deviceIds = $devices->pluck('id')->toArray(); $activeDevices = $this->customerInfoService->getActiveDevicesList($deviceIds); $deviceCount = $this->customerInfoService->getDevicesCount($deviceIds); $activeDeviceIds = collect($activeDevices['activeDevices'])->pluck('entityId')->pluck('id')->toArray(); $getDevices = Device::with('customer:id,title')->whereIn('id', $activeDeviceIds)->get(['id', 'name', 'customer_id', 'type', 'created_at']); $liveDevices = $getDevices->map(function($device){ return [ 'deviceId' => $device->id, 'deviceName' => $device->name, 'deviceType' => $device->type, 'deviceCustomer' => $device->customer->title, 'deviceCreatedAt' => $device->created_at ?? 'N/A' ]; }); return response()->json(['success' => true, 'totalDevices' => $deviceCount['totalDevices'] ?? 0, 'activeDevices' => $deviceCount['activeDevices'] ?? 0, 'data' => $liveDevices]); } catch(Exception $e){ return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getDeviceIndicators($assetId){ try { $token = readHeaderToken(); $cacheKey = "device_indicators_{$token['sub']}_asset_{$assetId}"; // $cachedData = Cache::remember($cacheKey, now()->addHours(value: 1), function () use ($token, $assetId) { $assetDeviceListing = $this->getUserAssetLinkWithDevices($token['sub'], $assetId); $assetLink = $assetDeviceListing->map(function($link){ $asset = $link->asset; $deviceData = $asset->devices->map(function($device){ $deviceProfile = $this->getDeviceWithProfile($device->id); $deviceProfileId = $deviceProfile?->deviceProfile?->id; $deviceProfileName = $deviceProfile?->deviceProfile?->name; $timeseriesList = $this->getDashboardTimeseriesKeysForProfile($deviceProfileId); $keyNameList = $timeseriesList->pluck('key_name')->implode(','); $displayNameMap = $timeseriesList->pluck('display_name', 'key_name')->toArray(); $telemetryValue = $this->customerInfoService->fetchTelemetryData($device->id, $keyNameList); $data = $telemetryValue instanceof \Illuminate\Http\JsonResponse ? $telemetryValue->getData(true) : $telemetryValue; $transformedTelemetry = $this->processDeviceIndicators($data, $device->id, $displayNameMap); return [ 'deviceId' => $device->id, 'deviceName' => $device->name, 'deviceType' => $deviceProfileName, 'deviceSensor' => $device->sensor, 'indicator' => $transformedTelemetry ]; })->values(); return [ 'success' => true, 'data' => $deviceData ]; }); // return $assetLink; // }); return response()->json($assetLink); } catch(Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } private function getUserAssetLinkWithDevices($userId = null, $assetId = null) { $query = UserAssetLink::with('asset.devices') ->where('user_id', $userId); if ($assetId) { $query->where('asset_id', $assetId); } return $query->get(); } private function getDeviceWithProfile($deviceId) { return Device::with('deviceProfile')->find($deviceId); } private function getDashboardTimeseriesKeysForProfile($deviceProfileId) { return TimeseriesKeyMaster::where('display_on_dashboard', true) ->where('device_profile_xid', $deviceProfileId) ->get(['key_name', 'display_name']); } private function processDeviceIndicators($data, $deviceId, $displayNameMap) { $transformedTelemetry = []; if (!empty($data) && is_array($data)) { foreach ($data as $key => $items) { foreach ($items as $item) { $color = $this->determineIndicatorColor($key, $item['value']); // Calculate average over past 6 hours $averageVal = $this->calculateAverageOverPastHours($deviceId, $key, 6); $transformedTelemetry[] = [ 'display_name' => $displayNameMap[$key] ?? $key, 'value' => $item['value'], 'averageVal' => number_format((float)$averageVal, 2, '.', ''), 'color' => $color ]; } } } return $transformedTelemetry; } private function determineIndicatorColor($key, $value) { if ($key == "PowerLoss_value") { if ($value > 5) { return 'red'; } elseif ($value > 30) { return 'orange'; } return 'green'; } if ($value > 70) { return 'green'; } elseif ($value > 30) { return 'orange'; } return 'red'; } private function calculateAverageOverPastHours($deviceId, $key, $hours = 6) { $ts['startTs'] = Carbon::now()->subHours($hours)->timestamp * 1000; $ts['endTs'] = Carbon::now()->timestamp * 1000; $pastValues = $this->customerInfoService->fetchTelemetryData($deviceId, $key, $ts); $pastValTotal = 0; $pastValTotalCount = 0; if (!empty($pastValues)) { foreach ($pastValues as $past) { foreach ($past as $value) { $pastValTotal += $value['value']; $pastValTotalCount++; } } } return $pastValTotalCount > 0 ? round($pastValTotal / $pastValTotalCount, 2) : 0; } public function getAlerts($deviceId){ try { $token = readHeaderToken(); $cacheKey = "device_alerts_{$token['sub']}_device_{$deviceId}"; if (!$this->validateUserHasAccessToDevice($token['sub'], $deviceId)) { return response()->json(['success' => true, 'message' => 'Device not found'], 404); } // $cachedData = Cache::remember($cacheKey, now()->addHours(value: 1), function () use ($deviceId) { $deviceParams = $this->getDeviceAlertParameters($deviceId); $keyNameList = $deviceParams->pluck('key_name')->implode(','); $displayNameMap = $deviceParams->pluck('display_name', 'key_name')->toArray(); $telemetryValue = $this->customerInfoService->fetchTelemetryData($deviceId, $keyNameList); $data = $telemetryValue instanceof \Illuminate\Http\JsonResponse ? $telemetryValue->getData(true) : $telemetryValue; $transformedTelemetry = []; $dateTime = null; if (!empty($data) && is_array($data)) { foreach ($data as $key => $items) { foreach ($items as $item) { $alertPoints = $this->getAlertPointsForKey($key, $item['value'], $displayNameMap); $dateTime = Carbon::createFromTimestamp($item['ts'] / 1000)->format('d-M-Y H:i:s'); if($alertPoints){ $transformedTelemetry[] = [ 'display_name' => $displayNameMap[$key] ?? $key, 'alert_msg' => $alertPoints ?: ["No Alerts & Instructions"] ]; } } } } $response = [ 'success' => true, 'updated_time' => $this->telemetryService->convertToUserTimezone($dateTime), 'data' => $transformedTelemetry ]; // }); return response()->json($response); } catch(Exception $e){ return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } private function validateUserHasAccessToDevice($userId, $deviceId) { $userDevices = UserAssetLink::with('asset.devices') ->where('user_id', $userId) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $deviceIds = $userDevices->pluck('id')->toArray(); return in_array($deviceId, $deviceIds); } private function getDeviceAlertParameters($deviceId) { return TimeseriesKeyMaster::select('key_name', 'display_name') ->where('display_on_alerts', 1) ->whereHas('device', function ($query) use ($deviceId) { $query->where('id', $deviceId); }) ->get(); } private function getAlertPointsForKey($key, $value, $displayNameMap) { $displayName = $displayNameMap[$key] ?? $key; $timeseriesId = TimeseriesKeyMaster::where('display_name', $displayName)->first('id'); if (!$timeseriesId) { return []; } $fetchMsg = TimeseriesAlertMessage::where('timeseries_key_master_xid', $timeseriesId['id']) ->where('min_value', '<=', $value) ->where('max_value', '>=', $value) ->first(['alert_msg']); return !empty($fetchMsg?->alert_msg) ? explode("\n", trim($fetchMsg->alert_msg)) : []; } public function getLiveDevice($deviceId){ try { if (!$this->validateUserHasAccessToDevice(readHeaderToken()['sub'], $deviceId)) { return response()->json([ 'success' => false, 'error' => 'You are not authorized to access this device' ], 403); } $deviceType = Device::where('id', $deviceId)->first('type'); $deviceCount = $this->customerInfoService->getDevicesCount(["$deviceId"]); return response()->json([ 'success' => true, 'active' => $deviceCount['activeDevices'] ? true : false, 'deviceType' => $deviceType->type ]); } catch(Exception $e){ Log::error("Error checking device status: " . $e->getMessage(), ['device_id' => $deviceId]); return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getGlobalIndicators($deviceId){ try { $token = readHeaderToken(); $cacheKey = "global_indicators_{$token['sub']}_device_{$deviceId}"; if (!$this->validateUserHasAccessToDevice($token['sub'], $deviceId)) { return response()->json([ 'success' => false, 'error' => 'Device not found or you do not have access to it' ], 404); } // Cache the response for 1 hour // $cachedData = Cache::remember($cacheKey, now()->addHours(value: 1), function () use ($deviceId) { $deviceParams = $this->getPopupTimeseriesKeys($deviceId); if ($deviceParams->isEmpty()) { return [ 'success' => false, 'error' => 'No indicator parameters found for this device' ]; } $keyNameList = $deviceParams->pluck('key_name')->implode(','); $displayNameMap = $deviceParams->pluck('display_name', 'key_name')->toArray(); $telemetryValue = $this->customerInfoService->fetchTelemetryData($deviceId, $keyNameList); $data = $telemetryValue instanceof \Illuminate\Http\JsonResponse ? $telemetryValue->getData(true) : $telemetryValue; $deviceLiveStatus = $this->getLiveDevice($deviceId); $deviceLiveStatus = $deviceLiveStatus instanceof \Illuminate\Http\JsonResponse ? $deviceLiveStatus->getData(true) : $deviceLiveStatus; // Transform the data using our TelemetryService $transformed = $this->telemetryService->transformTelemetryData($data, $displayNameMap, $deviceLiveStatus['active']); $response = [ 'success' => true, 'updated_time' => $transformed['dateTime'] ? $this->telemetryService->convertToUserTimezone($transformed['dateTime']) : null, 'data' => $transformed['telemetry'] ]; // }); return response()->json($response); } catch(Exception $e){ Log::error("Error fetching global indicators: " . $e->getMessage(), ['device_id' => $deviceId]); return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } private function getPopupTimeseriesKeys($deviceId) { return TimeseriesKeyMaster::select('key_name', 'display_name', 'display_on_popup_sequence') ->where('display_on_popup', 1) ->whereHas('device', function ($query) use ($deviceId) { $query->where('id', $deviceId); }) ->orderBy('display_on_popup_sequence') ->get(); } public function getTrends($deviceId) { try { $token = readHeaderToken(); $cacheKey = "trends_{$token['sub']}_device_{$deviceId}"; $userDevices = UserAssetLink::with('asset.devices') ->where('user_id', $token['sub']) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $deviceIds = $userDevices->pluck('id')->toArray(); if (!in_array($deviceId, $deviceIds)) { return response()->json(['success' => true, 'message' => 'Device not found'], 404); } // Cache the response for 1 hour // $cachedData = Cache::remember($cacheKey, now()->addHours(value: 1), function () use ($deviceId) { $dates = collect(range(0, 6))->map(function ($i) { return Carbon::now()->subDays($i)->format('M d, Y'); })->reverse()->values()->toArray(); $graph1 = $graph2 = []; foreach ($dates as $date) { $dateTs[] = Carbon::createFromFormat('M d, Y', $date)->timestamp * 1000; $ts['startTs'] = Carbon::createFromFormat('M d, Y', $date)->startOfDay()->timestamp * 1000; $ts['endTs'] = Carbon::createFromFormat('M d, Y', $date)->endOfDay()->timestamp * 1000; $deviceProfile = Device::with('deviceProfile')->find($deviceId); $deviceProfileId = $deviceProfile?->deviceProfile?->id; $parameters = parameters(); $value1 = $value2 = $param1 = $param2 = []; $key1 = explode(',', $parameters[$deviceProfileId]['keyNameList1']); $key2 = explode(',', $parameters[$deviceProfileId]['keyNameList2']); $x1 = TimeseriesKeyMaster::where('key_name', $key1[0])->first('display_name'); $x2 = TimeseriesKeyMaster::where('key_name', $key1[1])->first('display_name'); $y1 = TimeseriesKeyMaster::where('key_name', $key2[0])->first('display_name'); $y2 = TimeseriesKeyMaster::where('key_name', $key2[1])->first('display_name'); $min1 = $key1[0] === 'PowerLoss_value' ? 0 : 0; $max1 = $key1[0] === 'PowerLoss_value' ? 10 : 100; $telemetryValue1 = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, $parameters[$deviceProfileId]['keyNameList1'], $ts); $trendsData1 = $telemetryValue1 instanceof \Illuminate\Http\JsonResponse ? $telemetryValue1->getData(true) : $telemetryValue1; $telemetryValue2 = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, $parameters[$deviceProfileId]['keyNameList2'], $ts); $trendsData2 = $telemetryValue2 instanceof \Illuminate\Http\JsonResponse ? $telemetryValue2->getData(true) : $telemetryValue2; foreach ($trendsData1 as $key => $trend) { $displayName = TimeseriesKeyMaster::where('key_name', $key)->first('display_name'); $param1[] = $displayName['display_name']; foreach ($trend as $val) { $value1[0][$displayName['display_name']][] = $val['value']; } } foreach ($trendsData2 as $key => $trend) { $displayName = TimeseriesKeyMaster::where('key_name', $key)->first('display_name'); $param2[] = $displayName['display_name']; foreach ($trend as $val) { $value2[0][$displayName['display_name']][] = $val['value']; } } $graph1['y1'] = ['name' => $x1['display_name'], 'min' => $min1, 'max' => $max1]; $graph1['y2'] = ['name' => $x2['display_name'], 'min' => 0, 'max' => 50000]; $graph1[$date] = $value1; $graph2['y1'] = ['name' => $y1['display_name'], 'min' => 0, 'max' => 100]; $graph2['y2'] = ['name' => $y2['display_name'], 'min' => 0, 'max' => 50000]; $graph2[$date] = $value2; } $response = [ 'success' => true, 'graph1' => $graph1, 'graph2' => $graph2, ]; // }); return response()->json($response); } catch (Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getCylinderSpecificIndicators($deviceId) { try { $token = readHeaderToken(); $cacheKey = "cylinder_specific_indicators_device_{$deviceId}"; $userDevices = UserAssetLink::with('asset.devices') ->where('user_id', $token['sub']) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $deviceIds = $userDevices->pluck('id')->toArray(); if (!in_array($deviceId, $deviceIds)) { return response()->json(['success' => true, 'message' => 'Device not found'], 404); } // $data = Cache::remember($cacheKey, now()->addHours(value: 1), function () use ($deviceId) { $device = Device::find($deviceId, ['device_profile_id', 'type']); $profileId = $device->device_profile_id; $isGasEngine = $device->type === 'Gas Engine'; $cylindersToShow = ['Compression Condition','Injection Condition','Bearing Condition','Condition of Cyl Moving Parts']; if ($isGasEngine) { $cylindersToShow[] = 'Misfiring'; } $global = [ 0 => 'Compression_valueInPercent', 1 => 'InjectionCondition_valueInPercent', 2 => 'Bearing_valueInPercent', 3 => 'BearingBis_valueInPercent', 4 => 'Misfiring_valueInPercent' ]; $firingOrderKeys = TimeseriesKeyMaster::where('display_firing_order', 1) ->where('device_profile_xid', $profileId) ->pluck('key_name') ->toArray(); $firingOrderData = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, implode(',', $firingOrderKeys)); $data = []; foreach ($cylindersToShow as $index => $title) { $cylinderKeys = TimeseriesKeyMaster::where('display_cylinder_specific', $index + 1) ->where('device_profile_xid', $profileId) ->pluck('key_name') ->toArray(); $globalKey = $global[$index]; $colorData = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, implode(',', $cylinderKeys)); $globalValue = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, $globalKey); $globalRaw = $globalValue[$globalKey][0]['value'] ?? 0; $globalValueColor = $globalRaw > 70 ? 'green' : ($globalRaw > 30 ? 'orange' : 'red'); $response = []; $i = 1; foreach ($firingOrderData as $orderKey => $values) { $cylinderNum = $values[0]['value'] ?? 0; $name = 'Cyl' . $cylinderNum; $prefixMap = [ 0 => 'Compression', 1 => 'Injection', 2 => 'Bearing', 3 => 'InjectionCondition', 4 => 'Misfiring' ]; $prefix = $prefixMap[$index]; $colorKey = "{$prefix}_cylinderHealth_" . $i++; $val = $colorData[$colorKey][0]['value'] ?? null; $color = is_null($val) ? 'grey' : ($val > 70 ? 'green' : ($val > 30 ? 'orange' : 'red')); $response[] = [ 'name' => $name, 'value' => $val, 'color' => $color, ]; } $data[] = [ 'title' => $title, 'global' => [ 'value' => $globalRaw, 'color' => $globalValueColor, ], 'data' => $response ]; } $response = ['success' => true, 'data' => $data]; // }); return response()->json($response); } catch (Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getPeakPressure($deviceId) { try { $token = readHeaderToken(); $cacheKey = "peak_pressure_device_{$deviceId}"; $userDevices = UserAssetLink::with('asset.devices') ->where('user_id', $token['sub']) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $deviceIds = $userDevices->pluck('id')->toArray(); if (!in_array($deviceId, $deviceIds)) { return response()->json(['success' => true, 'message' => 'Device not found'], 404); } // $data = Cache::remember($cacheKey, now()->addHours(value: 1), function () use ($deviceId) { $device = Device::find($deviceId, ['device_profile_id', 'type']); $profileId = $device->device_profile_id; $pressureValKey = 'Pressure_value'; $pressureVal = $this->customerInfoService->fetchTelemetryData($deviceId, $pressureValKey); if ($pressureVal[$pressureValKey][0]['value'] == 0) { return ['success' => false, 'message' => 'No data available']; } $firingOrderKeys = TimeseriesKeyMaster::where('display_firing_order', 1) ->where('device_profile_xid', $profileId) ->pluck('key_name') ->toArray(); $cylinderKeys = TimeseriesKeyMaster::where('display_cylinder_specific', 6) ->where('device_profile_xid', $profileId) ->pluck('key_name') ->toArray(); $firingOrderData = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, implode(',', $firingOrderKeys)); $valData = app(CustomerInfoService::class)->fetchTelemetryData($deviceId, implode(',', $cylinderKeys)); $i = 1; $response = []; foreach ($firingOrderData as $orderKey => $values) { $cylinderNum = $values[0]['value'] ?? 0; $name = 'Cyl' . $cylinderNum; $valKey = "Pressure_cylinderHealth_" . $i++; $val = $valData[$valKey][0]['value'] ?? null; $response[] = [ 'name' => $name, 'value' => $val, ]; } $response = ['success' => true, 'data' => $response]; // }); return response()->json($response); } catch (Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getDeviceByAsset($assetId){ $deviceList = Device::where('asset_id', $assetId)->select('id','name')->get()->toArray(); return response()->json($deviceList); } public function getAdminAlarms(Request $request){ try { if($request->assetIds){ $getDeviceByAsset = Device::whereIn('asset_id', $request->assetIds)->pluck('id')->toArray(); }else{ $getDeviceByAsset = $request->deviceIds; } $data = [ 'statusList' => $request->statusList ?? ['ACTIVE'], 'severityList' => $request->severityList, 'startTs' => $request->startTs, 'endTs' => $request->endTs, 'deviceIds' => $request->deviceIds ?? $getDeviceByAsset, ]; $allDevices = Device::pluck('id')->toArray(); $alarms = $this->customerInfoService->fetchDeviceAlarms($allDevices, $data); return response()->json(['success' => true, 'data' => $alarms]); } catch(Exception $e){ return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getUserAssets(){ $token = readHeaderToken(); $userId = $token['sub']; $userAssets = UserAssetLink::with('asset:id,name') ->where(['user_id' => $userId, 'active' => 1]) ->get() ->map(function($link) { return [ 'id' => $link->asset->id, 'name' => $link->asset->name ]; }); return response()->json($userAssets); } public function getUserDeviceByAsset($assetId){ $token = readHeaderToken(); $userDevices = UserAssetLink::with('asset.devices') ->where(['user_id' => $token['sub'], 'active' => 1, 'asset_id' => $assetId]) ->get() ->pluck('asset.devices') ->flatten() ->select('id','name'); return response()->json($userDevices); } public function getUserAlarms(Request $request){ try { $token = readHeaderToken(); if($request->assetIds) { $userDevices = UserAssetLink::with('asset.devices') ->where(['user_id' => $token['sub'], 'active' => 1]) ->whereIn('asset_id', $request->assetIds) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $getDeviceByAsset = $userDevices->pluck('id')->toArray(); } else { $getDeviceByAsset = $request->deviceIds; } $data = [ 'statusList' => $request->statusList ?? ['ACTIVE'], 'severityList' => $request->severityList, 'startTs' => $request->startTs, 'endTs' => $request->endTs, 'deviceIds' => $request->deviceIds ?? $getDeviceByAsset, ]; $userDevices = UserAssetLink::with('asset.devices') ->where(['user_id' => $token['sub'], 'active' => 1]) ->get() ->pluck('asset.devices') ->flatten() ->unique('id'); $allDevices = $userDevices->pluck('id')->toArray(); $alarms = $this->customerInfoService->fetchDeviceAlarms($allDevices, $data); return response()->json(['success' => true, 'data' => $alarms]); } catch(Exception $e){ return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } }