From a4227ab7f592e4ccc641be9564c11cb96a119c0f Mon Sep 17 00:00:00 2001 From: kshitige Date: Mon, 7 Apr 2025 11:43:37 +0530 Subject: [PATCH 1/2] changes --- .../Controllers/APIS/CustomerApi/TelemetryController.php | 9 +++------ routes/admin_api.php | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php index 8e81d95..7ab700b 100644 --- a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php +++ b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php @@ -596,7 +596,7 @@ class TelemetryController extends Controller // Get authenticated user's customer ID $token = readHeaderToken(); $customerId = User::where('id', $token['sub'])->value('customer_id'); - dd($customerId); + // dd($customerId); if (!$customerId) { return response()->json(['error' => 'Unauthorized - Invalid user'], 401); @@ -622,11 +622,9 @@ class TelemetryController extends Controller return response()->json(['error' => 'Asset not found or access denied'], 404); } - // 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 + $endTsMs = now()->timestamp * 1000; + $startTsMs = $endTsMs - (30 * 60 * 1000); - // Get devices that belong to both the asset and customer $devices = Device::with([ 'deviceProfile:id,name', 'timeseriesKeys' => function ($query) { @@ -649,7 +647,6 @@ class TelemetryController extends Controller $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); diff --git a/routes/admin_api.php b/routes/admin_api.php index a9607c7..2080ec7 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -68,5 +68,3 @@ Route::post('/alarm/clear/{id}', [AlarmControllerCommon::class, 'clearAlarmById' Route::get('/rule-chains', [RuleChainController::class, 'getRuleChainList'])->name('list.RuleChain'); Route::get('/rule-chains-export', [RuleChainController::class, 'exportruleChain'])->name('export.RuleChain'); Route::get('/rule-chains/{ruleChainId}', [RuleChainController::class, 'showruleChain'])->name('show.RuleChain'); - - -- 2.34.1 From 9e67e51f72cc297f2e070984c511b9bd6112c2ec Mon Sep 17 00:00:00 2001 From: kshitige Date: Mon, 7 Apr 2025 12:10:14 +0530 Subject: [PATCH 2/2] changes in telemetry asset --- .../APIS/CustomerApi/TelemetryController.php | 815 +++--------------- 1 file changed, 141 insertions(+), 674 deletions(-) diff --git a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php index 7ab700b..fcaf259 100644 --- a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php +++ b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php @@ -9,6 +9,7 @@ use App\Models\Device; use App\Models\TimeseriesAlertMessage; use App\Models\TimeseriesKeyMaster; use App\Models\User; +use App\Models\UserAssetLink; use App\Services\AlarmService; use App\Services\CustomerInfoService; use Illuminate\Container\Attributes\DB; @@ -34,698 +35,164 @@ class TelemetryController extends Controller - - - - - - - // public function telemetryDataAsset(Request $request) - // { - // $validator = Validator::make($request->all(), [ - // 'asset_id' => 'required|string', - // 'startTs' => 'nullable|string', - // 'endTs' => 'nullable|string', - // ]); - - // if ($validator->fails()) { - // return jsonResponseWithErrorMessage($validator->errors()->first(), 400); - // } - - // $assetId = $request->input('asset_id'); - // $startTs = $request->input('startTs') ?: now()->subHours(24)->timestamp * 1000; // Default: last 24 hrs - // $endTs = $request->input('endTs') ?: now()->timestamp * 1000; - - // $devices = Device::with('deviceProfile') - // ->where('asset_id', $assetId) - // ->get(); - - // if ($devices->isEmpty()) { - // return response()->json(['error' => 'No devices found for the asset'], 404); - // } - - // $response = []; - - // foreach ($devices as $device) { - // $filteredTelemetry = []; - - // // Fetch telemetry data - // $keysData = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id) - // ->where('display_on_dashboard', 1) - // ->get(['key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); - - // $keyNames = $keysData->pluck('key_name')->toArray(); - - // // Retrieve telemetry data - // $telemetryResponse = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTs, $endTs); - - // foreach ($keysData as $keyData) { - // $keyName = $keyData->key_name; - - // if (isset($telemetryResponse[$keyName])) { - // foreach ($telemetryResponse[$keyName] as $item) { - // // 💡 Check alert status for each telemetry key - // $alert = $this->checkTelemetryKeyAlert($device->id, $keyName); - - // $filteredTelemetry[] = [ - // 'key_name' => $keyName, - // 'display_name' => $keyData->display_name, - // 'display_on_dashboard' => $keyData->display_on_dashboard, - // 'display_on_popup' => $keyData->display_on_popup, - // 'timestamp' => $item['ts'] ?? null, - // 'value' => $item['value'] ?? null, - // 'alert' => $alert // ✅ Add alert status for each key - // ]; - // } - // } - // } - - // $response[] = [ - // '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' => $filteredTelemetry, - // ]; - // } - - // return response()->json(['telemetry' => $response]); - // } - - - // public function telemetryDataAsset(Request $request) - // { - // $validator = Validator::make($request->all(), [ - // 'asset_id' => 'required|string', - // 'startTs' => 'nullable|string', - // 'endTs' => 'nullable|string', - // ]); - - // if ($validator->fails()) { - // return jsonResponseWithErrorMessage($validator->errors()->first(), 400); - // } - - // $assetId = $request->input('asset_id'); - // $startTs = $request->input('startTs') ?: null; - // $endTs = $request->input('endTs') ?: null; - - // // Fetch devices associated with the asset - // $devices = Device::with('deviceProfile') - // ->where('asset_id', $assetId) - // ->get(); - - // if ($devices->isEmpty()) { - // return response()->json(['error' => 'No devices found for the asset'], 404); - // } - - // $response = []; - - // foreach ($devices as $device) { - // $telemetry = []; - - // $keysData = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id) - // ->where(function ($query) { - // $query->where('display_on_dashboard', true) - // ->orWhere('display_on_popup', true); - // }) - // ->get(['key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); - - // $keyNames = $keysData->pluck('key_name')->toArray(); - - // // Log key names for debugging - // // Log::info('Key Names for Device', ['device_id' => $device->id, 'key_names' => $keyNames]); - - // // Fetch telemetry data - // $telemetryResponse = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTs, $endTs); - - // foreach ($keysData as $keyData) { - // $keyName = $keyData->key_name; - - // if (isset($telemetryResponse[$keyName])) { - // foreach ($telemetryResponse[$keyName] as $item) { - // $telemetry[] = [ - // 'key_name' => $keyName, - // 'display_name' => $keyData->display_name, - // 'display_on_dashboard' => $keyData->display_on_dashboard, - // 'display_on_popup' => $keyData->display_on_popup, - // 'timestamp' => $item['ts'] ?? null, - // 'value' => $item['value'] ?? null, - // ]; - // } - // } - // } - - // $response[] = [ - // '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]); - // } - - - // public function telemetryDataAsset(Request $request) - // { - // $validator = Validator::make($request->all(), [ - // 'asset_id' => 'required|string', - // 'startTs' => 'nullable|string', - // 'endTs' => 'nullable|string', - // ]); - - // if ($validator->fails()) { - // return jsonResponseWithErrorMessage($validator->errors()->first(), 400); - // } - - // $assetId = $request->input('asset_id'); - // $startTs = $request->input('startTs') ?: now()->subHours(24)->timestamp * 1000; // Default: last 24 hrs - // $endTs = $request->input('endTs') ?: now()->timestamp * 1000; - - // $devices = Device::with('deviceProfile') - // ->where('asset_id', $assetId) - // ->get(); - - // if ($devices->isEmpty()) { - // return response()->json(['error' => 'No devices found for the asset'], 404); - // } - - // $response = []; - - // foreach ($devices as $device) { - // $telemetry = []; - - // // Fetch telemetry keys - // $keysData = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id) - // ->where(function ($query) { - // $query->where('display_on_dashboard', true) - // ->orWhere('display_on_popup', true); - // }) - // ->get(['key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); - - // $keyNames = $keysData->pluck('key_name')->toArray(); - - // // Fetch telemetry data - // $telemetryResponse = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTs, $endTs); - - // // Fetch alarms for the device and map by telemetry key - // $alarmMap = $this->getDeviceAlarmsForTelemetry($device->id); - - // foreach ($keysData as $keyData) { - // $keyName = $keyData->key_name; - - // if (isset($telemetryResponse[$keyName])) { - // foreach ($telemetryResponse[$keyName] as $item) { - // // Check if the telemetry key has an alarm - // $alert = isset($alarmMap[$keyName]); - - // $telemetry[] = [ - // 'key_name' => $keyName, - // 'display_name' => $keyData->display_name, - // 'display_on_dashboard' => $keyData->display_on_dashboard, - // 'display_on_popup' => $keyData->display_on_popup, - // 'timestamp' => $item['ts'] ?? null, - // 'value' => $item['value'] ?? null, - // 'alert' => $alert // ✅ Display alert status - // ]; - // } - // } - // } - - // $response[] = [ - // '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]); - // } - - // public function telemetryDataAsset(Request $request) - // { - // Log::info("Received telemetryDataAsset request.", $request->all()); - - // $validator = Validator::make($request->all(), [ - // 'asset_id' => 'required|string', - // 'startTs' => 'nullable|string', - // 'endTs' => 'nullable|string', - // ]); - - // if ($validator->fails()) { - // Log::error("Validation failed: " . $validator->errors()->first()); - // return jsonResponseWithErrorMessage($validator->errors()->first(), 400); - // } - - // $assetId = $request->input('asset_id'); - // $startTs = $request->input('startTs') ?: now()->subHours(24)->timestamp * 1000; // Default: last 24 hrs - // $endTs = $request->input('endTs') ?: now()->timestamp * 1000; - - // Log::info("Telemetry time range: Start => {$startTs}, End => {$endTs}"); - - // // Fetch devices associated with the asset - // $devices = Device::with('deviceProfile') - // ->where('asset_id', $assetId) - // ->get(); - - // if ($devices->isEmpty()) { - // Log::warning("No devices found for asset ID: {$assetId}"); - // return response()->json(['error' => 'No devices found for the asset'], 404); - // } - - // Log::info("Found " . $devices->count() . " devices for asset ID: {$assetId}"); - - // $response = []; - - // foreach ($devices as $device) { - // $telemetry = []; - - // Log::info("Processing device ID: {$device->id}"); - - // // Fetch telemetry keys - // $keysData = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id) - // ->where(function ($query) { - // $query->where('display_on_dashboard', true) - // ->orWhere('display_on_popup', true); - // }) - // ->get(['key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); - - // Log::info("Fetched " . $keysData->count() . " telemetry keys for device ID: {$device->id}"); - - // $keyNames = $keysData->pluck('key_name')->toArray(); - - // // Fetch telemetry data - // $telemetryResponse = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTs, $endTs); - - // Log::info("Fetched telemetry data for device ID: {$device->id}"); - - // // Fetch alarms for the device and map by telemetry key - // $alarmMap = $this->getDeviceAlarmsForTelemetry($device->id); - // Log::info("Fetched alarms for device ID: {$device->id}", $alarmMap); - - // foreach ($keysData as $keyData) { - // $keyName = $keyData->key_name; - - // if (isset($telemetryResponse[$keyName])) { - // foreach ($telemetryResponse[$keyName] as $item) { - // // Check if the telemetry key has an alarm - // $alert = isset($alarmMap[$keyName]); - - // $telemetry[] = [ - // 'key_name' => $keyName, - // 'display_name' => $keyData->display_name, - // 'display_on_dashboard' => $keyData->display_on_dashboard, - // 'display_on_popup' => $keyData->display_on_popup, - // 'timestamp' => $item['ts'] ?? null, - // 'value' => $item['value'] ?? null, - // 'alert' => $alert // ✅ Display alert status - // ]; - // } - // } - // } - - // $response[] = [ - // '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, - // ]; - - // Log::info("Processed telemetry for device ID: {$device->id}"); - // } - - // Log::info("Telemetry data successfully generated for asset ID: {$assetId}"); - - // return response()->json(['telemetry' => $response]); - // } - - // public function telemetryDataAsset(Request $request) - // { - // $token = readHeaderToken(); - // $customerId = User::where('id', $token['sub'])->value('customer_id'); - - // $validator = Validator::make($request->all(), [ - // 'asset_id' => 'required|string', - // 'startTs' => 'nullable|string', - // 'endTs' => 'nullable|string', - // ]); - - // if ($validator->fails()) { - // return jsonResponseWithErrorMessage($validator->errors()->first(), 400); - // } - - // $assetId = $request->input('asset_id'); - // $startTs = $request->input('startTs') ?: now()->subHours(24)->timestamp * 1000; - // $endTs = $request->input('endTs') ?: now()->timestamp * 1000; - - // $devices = Device::with([ - // 'deviceProfile', - // '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 asset'], 404); - // } - - // $response = $devices->map(function ($device) use ($startTs, $endTs) { - // $keysData = $device->timeseriesKeys; - - // $keyNames = $keysData->pluck('key_name')->toArray(); - // $telemetryResponse = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTs, $endTs); - - // $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 ($telemetryResponse, $alarmMap, $alertMessages) { - // return collect($telemetryResponse[$keyData->key_name] ?? [])->map(function ($item) use ($keyData, $alarmMap, $alertMessages) { - // $keyName = $keyData->key_name; - // $alert = isset($alarmMap[$keyName]); - // $value = floatval($item['value'] ?? 0); - // $colorCode = null; - - // // Default to grey if value is 0 - // if ($value == 0) { - // $colorCode = "grey"; - // } else { - // // Check alert messages for this key - // if (isset($alertMessages[$keyData->id])) { - // foreach ($alertMessages[$keyData->id] as $alertMsg) { - // // If min_value or max_value is null, return null - // if (is_null($alertMsg->min_value) || is_null($alertMsg->max_value)) { - // $colorCode = 'green'; - // break; - // } - - // if ($value >= floatval($alertMsg->min_value) && $value <= floatval($alertMsg->max_value)) { - // $colorCode = $alertMsg->color_code; - // break; - // } - // } - // } - // } - - // return [ - // 'key_name' => $keyName, - // 'display_name' => $keyData->display_name, - // 'display_on_dashboard' => $keyData->display_on_dashboard, - // 'display_on_popup' => $keyData->display_on_popup, - // 'timestamp' => $item['ts'] ?? null, - // 'value' => $value, - // 'alert' => $alert, - // 'color_code' => $colorCode, // Now handles null & grey cases - // ]; - // }); - // })->flatten(1); - - // 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' => array_values($telemetry->toArray()), - // ]; - // }); - - // return response()->json(['telemetry' => $response]); - // } - - - // public function telemetryDataAsset(Request $request) - // { - // $token = readHeaderToken(); - // $customerId = User::where('id', $token['sub'])->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'); - - // // Set timestamps in milliseconds for database query - // $endTsMs = now()->timestamp * 1000; // Current time in milliseconds - // $startTsMs = $endTsMs - (30 * 60 * 1000); // 5 minutes ago in milliseconds - - // $devices = Device::with([ - // 'deviceProfile', - // '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 asset'], 404); - // } - - // $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 based on start vs end values - // $trend = null; - // if ($startValue > 0) { - // if ($endValue > $startValue) { - // $trend = 'upward'; - // } elseif ($endValue < $startValue) { - // $trend = 'downward'; - // } else { - // $trend = 'stable'; - // } - // } - - // // Format timestamp properly (convert to seconds if in milliseconds) - // if (!isset($currentData['ts'])) { - // $timestamp = now()->timestamp; - // } elseif (is_float($currentData['ts']) || $currentData['ts'] > 9999999999) { - // $timestamp = intval($currentData['ts'] / 1000); - // } else { - // $timestamp = $currentData['ts']; - // } - - // // Color code logic - // $colorCode = null; - // if ($endValue == 0) { - // $colorCode = "grey"; - // } else { - // if (isset($alertMessages[$keyData->id])) { - // foreach ($alertMessages[$keyData->id] as $alertMsg) { - // if (is_null($alertMsg->min_value) || is_null($alertMsg->max_value)) { - // $colorCode = 'green'; - // break; - // } - // if ($endValue >= floatval($alertMsg->min_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, - // ]; - // })->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), // Current period start (seconds) - // 'endTs' => intval($endTsMs / 1000), // Current period end (seconds) - // ] - // ]); - // } - public function telemetryDataAsset(Request $request) -{ - // Get authenticated user's customer ID - $token = readHeaderToken(); - $customerId = User::where('id', $token['sub'])->value('customer_id'); - // dd($customerId); + { + try { + $token = readHeaderToken(); + $userId = $token['sub']; + $customerId = User::where('id', $userId)->value('customer_id'); - if (!$customerId) { - return response()->json(['error' => 'Unauthorized - Invalid user'], 401); - } + // Validate request + $validator = Validator::make($request->all(), [ + 'asset_id' => 'required|string', + ]); - // 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'); - - $assetExists = Asset::where('id', $assetId) - ->where('customer_xid', $customerId)->exists(); - - // dd($assetExists); - - if (!$assetExists) { - return response()->json(['error' => 'Asset not found or access denied'], 404); - } - - $endTsMs = now()->timestamp * 1000; - $startTsMs = $endTsMs - (30 * 60 * 1000); - - $devices = 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']); + if ($validator->fails()) { + return jsonResponseWithErrorMessage($validator->errors()->first(), 400); } - ]) - ->where('asset_id', $assetId) - ->where('customer_id', $customerId) - ->select(['id', 'device_profile_id', 'asset_id', 'customer_id']) - ->get(); - if ($devices->isEmpty()) { - return response()->json(['error' => 'No devices found for this asset'], 404); - } + $assetId = $request->input('asset_id'); - $response = $devices->map(function ($device) use ($startTsMs, $endTsMs) { - $keysData = $device->timeseriesKeys; - $keyNames = $keysData->pluck('key_name')->toArray(); + // Verify asset ownership + $assetLinkExists = UserAssetLink::where('user_id', $userId) + ->where('asset_id', $assetId) + ->exists(); - $startTelemetry = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTsMs, $startTsMs); - $endTelemetry = $this->customerInfoService->getTelemetryData($device, $keyNames, $endTsMs, $endTsMs); + if (!$assetLinkExists) { + return response()->json([ + 'error' => 'You are not authorized to access this asset', + 'code' => 'UNAUTHORIZED_ACCESS' + ], 403); + } - $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'); + // 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 - $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'; + // Get devices with their telemetry keys + $devices = Device::with([ + 'deviceProfile', + '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); } - // Format timestamp - $timestamp = now()->timestamp; - if (isset($endData['ts'])) { - $timestamp = ($endData['ts'] > 9999999999) ? intval($endData['ts'] / 1000) : $endData['ts']; - } + // Process telemetry data for each device + $response = $devices->map(function ($device) use ($startTsMs, $endTsMs) { + $keysData = $device->timeseriesKeys; + $keyNames = $keysData->pluck('key_name')->toArray(); - $colorCode = null; - if ($endValue != 0 && isset($alertMessages[$keyData->id])) { - foreach ($alertMessages[$keyData->id] as $alertMsg) { - if (is_null($alertMsg->min_value) && is_null($alertMsg->max_value)) { - $colorCode = 'green'; - break; + // 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'; + } } - if ($endValue >= floatval($alertMsg->min_value) && $endValue <= floatval($alertMsg->max_value)) { - $colorCode = $alertMsg->color_code; - break; + + // 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 ?: ($endValue == 0 ? 'grey' : 'green'), - ]; - })->filter()->values(); + 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); + } + } - 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), - ] - ]); -} private function getDeviceAlarmsForTelemetry($deviceId) { -- 2.34.1