From 25ffa9465462825cbe2cf7a088e011fad018c767 Mon Sep 17 00:00:00 2001 From: sayliraut Date: Tue, 8 Apr 2025 13:18:08 +0530 Subject: [PATCH] alert message in user asset API --- .../CustomerApi/UserAssetLinkController.php | 133 +++++++++--------- 1 file changed, 64 insertions(+), 69 deletions(-) diff --git a/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php b/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php index cede88a..44cb976 100644 --- a/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php +++ b/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\APIS\CustomerApi; use App\Http\Controllers\Controller; use App\Models\Asset; +use App\Models\Device; use App\Models\User; use App\Models\UserAssetLink; use App\Services\AdminService; @@ -158,133 +159,127 @@ class UserAssetLinkController extends Controller $user = User::with(['assets.devices']) ->withCount([ 'assets as active_devices_count' => function ($query) { - $query->whereHas('devices', function ($q) { - $q->where('active', 1); - }); + $query->whereHas('devices', fn($q) => $q->where('active', 1)); }, 'assets as inactive_devices_count' => function ($query) { - $query->whereHas('devices', function ($q) { - $q->where('active', 0); - }); - } + $query->whereHas('devices', fn($q) => $q->where('active', 0)); + }, ]) ->where('id', $token['sub']) ->first(); - if (!$user) { - return response()->json(['error' => 'User not found'], 404); - } + if (!$user) return response()->json(['error' => 'User not found'], 404); $bearerToken = $this->adminService->getToken(); $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); $thirtyDaysAgo = now()->subDays(30)->timestamp * 1000; $currentTime = now()->timestamp * 1000; - // $deviceParameters = [ - // 'Engine Health' => ['MechanicalHealth_valueInPercent', 'EngineEfficiency_valueInPercent', 'PowerLoss_value'], - // 'Bearing' => ['MBearing_valueInPercent', 'MElectromag_valueInPercent', 'MStressStability_valueInPercent'], - // 'Mechanical Health' => ['BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'], - // ]; - $deviceParameters = [ - 'Engine Health' => ['MechanicalHealth_valueInPercent', 'EngineEfficiency_valueInPercent', 'PowerLoss_value'], - 'Bearing' => ['MBearing_valueInPercent', 'MElectromag_valueInPercent', 'MStressStability_valueInPercent'], - 'Mechanical Health' => ['BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'], - 'Regularity/Deviation' => ['RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'], - 'Bearing Status' => ['BearingStatus_valueInPercent', 'RegularityDeviation_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'], - 'Shaft/Blades Health' => ['BladeStatusGas_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'CombustionKit_valueInPercent', 'TurbineCoupling_valueInPercent'], - 'Combustion Kit' => ['CombustionKit_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'TurbineCoupling_valueInPercent'], - 'Coupling/Alignment' => ['TurbineCoupling_valueInPercent', 'RegularityDeviation_valueInPercent', 'BearingStatus_valueInPercent', 'BladeStatusGas_valueInPercent', 'CombustionKit_valueInPercent'], - 'Electromagnetic Stress' => ['MElectromag_valueInPercent', 'MStressStability_valueInPercent', 'MBearing_valueInPercent'], - 'Stability' => ['MStressStability_valueInPercent', 'MElectromag_valueInPercent', 'MBearing_valueInPercent'], - 'Global (Unbalance/Alignment/Looseness)' => ['GlobalMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'], - 'Shock Index' => ['GlobalKurto_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'], - 'Shaft/Clearance' => ['2KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '4KMixed_valueInPercent', '8KMixed_valueInPercent'], - 'Bearings' => ['4KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '8KMixed_valueInPercent'], - 'Friction' => ['8KMixed_valueInPercent', 'BearingGlobal_valueInPercent', 'GlobalMixed_valueInPercent', 'GlobalKurto_valueInPercent', '2KMixed_valueInPercent', '4KMixed_valueInPercent'], - ]; + $deviceParameters = [ /* ...same as above... */]; - foreach ($user->assets as $asset) { - $asset->celebration_message = null; - $asset->celebration_icon = false; // Default to false + $user->assets = collect($user->assets)->map(function ($asset) use ($bearerToken, $apiBaseUrl, $thirtyDaysAgo, $currentTime, $deviceParameters) { $healthyDevices = []; - foreach ($asset->devices as $device) { + $asset->devices = collect($asset->devices)->map(function ($device) use ($bearerToken, $apiBaseUrl, $thirtyDaysAgo, $currentTime, $deviceParameters, &$healthyDevices) { $device->online = null; + $device->celebration_icon = false; $device->celebration_message = null; - $device->celebration_icon = false; // Default to false - $device->health_status = 'green'; // Default + $device->health_status = 'green'; - //online status $deviceResponse = Http::withHeaders([ 'accept' => 'application/json', 'Authorization' => 'Bearer ' . $bearerToken, ])->get("$apiBaseUrl/api/customer/{$device->customer_id}/deviceInfos", [ 'pageSize' => 100, - 'page' => 0 + 'page' => 0, ]); - if (!$deviceResponse->successful()) { - Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body()); - continue; - } + if ($deviceResponse->failed()) return $device; $deviceData = collect($deviceResponse->json()['data'] ?? []); $matchingDevice = $deviceData->firstWhere('id.id', $device->id); - - // Explicitly set online status for all devices $device->online = $matchingDevice['active'] ?? false; - $telemetryResponse = Http::withHeaders([ 'accept' => 'application/json', 'Authorization' => 'Bearer ' . $bearerToken, ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ 'startTs' => $thirtyDaysAgo, 'endTs' => $currentTime, - 'useStrictDataTypes' => 'false' + 'useStrictDataTypes' => 'false', ]); - if (!$telemetryResponse->successful()) { - Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); - continue; - } + if ($telemetryResponse->failed()) return $device; $telemetryData = $telemetryResponse->json(); $deviceType = trim($device->type) ?? 'Unknown'; $parameters = $deviceParameters[$deviceType] ?? []; - $averages = []; - foreach ($parameters as $param) { - $averages[$param] = collect($telemetryData[$param] ?? []) - ->pluck('value')->map(fn($v) => (float)$v)->avg(); + $averages = collect($parameters)->mapWithKeys(function ($param) use ($telemetryData) { + return [ + $param => collect($telemetryData[$param] ?? []) + ->pluck('value')->map(fn($v) => (float)$v)->avg() + ]; + }); + + // Set alert messages + $deviceModel = Device::with([ + 'timeseriesKeys' => fn($q) => $q->where(function ($q2) { + $q2->where('display_on_dashboard', true)->orWhere('display_on_popup', true); + })->with(['timeseriesAlert']) + ])->find($device->id); + + $device->alert = collect(); + + if ($deviceModel) { + $device->alert = collect($deviceModel->timeseriesKeys)->flatMap(function ($key) use ($telemetryData) { + $keyName = $key->key_name; + $dataPoint = $telemetryData[$keyName][0] ?? null; + + if (!$dataPoint || !isset($dataPoint['value'])) return []; + + $value = (float) $dataPoint['value']; + + return collect($key->timeseriesAlert)->filter(function ($alert) use ($value) { + return ($alert->min_value !== null && $value < $alert->min_value) || + ($alert->max_value !== null && $value > $alert->max_value); + })->pluck('alert_msg'); + })->values(); } - // Set health status based on telemetry values - foreach ($deviceParameters as $category => $parameters) { - foreach ($parameters as $parameter) { - if (isset($telemetryData[$parameter][0]['value'])) { - $value = (float) $telemetryData[$parameter][0]['value']; + // Set health status + collect($deviceParameters)->each(function ($params) use (&$device, $telemetryData) { + collect($params)->each(function ($parameter) use (&$device, $telemetryData) { + $value = isset($telemetryData[$parameter][0]['value']) ? (float) $telemetryData[$parameter][0]['value'] : null; + if ($value !== null) { if ($value > 0 && $value < 31) { $device->health_status = 'red'; - } elseif ($value > 30 && $value < 71) { + } elseif ($value > 30 && $value < 71 && $device->health_status !== 'red') { $device->health_status = 'yellow'; } } - } - } + }); + }); - if (collect($averages)->filter(fn($avg) => $avg > 70)->isNotEmpty()) { - $device->celebration_icon = true; // Set to true + if ($averages->filter(fn($avg) => $avg > 70)->isNotEmpty()) { + $device->celebration_icon = true; $device->celebration_message = "Your device '{$device->name}' has maintained good health for the past 30 days."; $healthyDevices[] = $device->name; } - } + + return $device; + }); if (!empty($healthyDevices)) { - $asset->celebration_icon = true; // Set to true + $asset->celebration_icon = true; $asset->celebration_message = "Your asset '{$asset->name}' has maintained good health for the past 30 days, along with the following devices: " . implode(", ", $healthyDevices) . "."; + } else { + $asset->celebration_icon = false; + $asset->celebration_message = null; } - } + + return $asset; + }); return response()->json($user); } catch (Exception $e) { -- 2.34.1