diff --git a/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php b/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php index 69562a5..1160102 100644 --- a/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php +++ b/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php @@ -148,149 +148,593 @@ class UserAssetLinkController extends Controller // } -// public function index() -// { -// try { -// $token = readHeaderToken(); + // public function index() + // { + // try { + // $token = readHeaderToken(); -// // Fetch user with assets and device counts -// $user = User::with(['assets.devices']) -// ->withCount([ -// 'assets as active_devices_count' => function ($query) { -// $query->whereHas('devices', function ($q) { -// $q->where('active', 1); -// }); -// }, -// 'assets as inactive_devices_count' => function ($query) { -// $query->whereHas('devices', function ($q) { -// $q->where('active', 0); -// }); -// } -// ]) -// ->where('id', $token['sub']) -// ->first(); + // // Fetch user with assets and device counts + // $user = User::with(['assets.devices']) + // ->withCount([ + // 'assets as active_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 1); + // }); + // }, + // 'assets as inactive_devices_count' => function ($query) { + // $query->whereHas('devices', function ($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'); + // $bearerToken = $this->adminService->getToken(); + // $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); -// foreach ($user->assets->flatMap->devices as $device) { -// $device->health_status = null; -// $device->online = null; -// $device->has_alarm = false; // Initialize alarm status to false + // foreach ($user->assets->flatMap->devices as $device) { + // $device->health_status = null; + // $device->online = null; + // $device->has_alarm = false; // Initialize alarm status to false -// // Fetch device details from API using customer_id -// $deviceResponse = Http::withHeaders([ -// 'accept' => 'application/json', -// 'Authorization' => 'Bearer ' . $bearerToken, -// ])->get("$apiBaseUrl/api/customer/{$device->customer_id}/deviceInfos", [ -// 'pageSize' => 100, -// 'page' => 0 -// ]); + // // Fetch device details from API using customer_id + // $deviceResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/customer/{$device->customer_id}/deviceInfos", [ + // 'pageSize' => 100, + // 'page' => 0 + // ]); -// if (!$deviceResponse->successful()) { -// Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body()); -// continue; -// } + // if (!$deviceResponse->successful()) { + // Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body()); + // continue; + // } -// $deviceData = collect($deviceResponse->json()['data'] ?? []); -// $matchingDevice = $deviceData->firstWhere('id.id', $device->id); + // $deviceData = collect($deviceResponse->json()['data'] ?? []); + // $matchingDevice = $deviceData->firstWhere('id.id', $device->id); -// // Set online status -// $device->online = $matchingDevice['active'] ?? null; + // // Set online status + // $device->online = $matchingDevice['active'] ?? null; -// // Fetch alarm data for the device (last 24 hours) -// $twentyFourHoursAgo = (time() - 86400) * 1000; // 24 hours ago in milliseconds -// $currentTime = time() * 1000; // current time in milliseconds + // // Fetch alarm data for the device (last 24 hours) + // $twentyFourHoursAgo = (time() - 86400) * 1000; // 24 hours ago in milliseconds + // $currentTime = time() * 1000; // current time in milliseconds -// $alarmResponse = Http::withHeaders([ -// 'accept' => 'application/json', -// 'Authorization' => 'Bearer ' . $bearerToken, -// ])->get("$apiBaseUrl/api/alarm/DEVICE/{$device->id}", [ -// 'pageSize' => 100, -// 'page' => 0, -// 'startTime' => $twentyFourHoursAgo, -// 'endTime' => $currentTime, -// 'fetchOriginator' => 'false', -// 'searchStatus' => 'ACTIVE,ACKNOWLEDGED,CLEARED' -// ]); + // $alarmResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/alarm/DEVICE/{$device->id}", [ + // 'pageSize' => 100, + // 'page' => 0, + // 'startTime' => $twentyFourHoursAgo, + // 'endTime' => $currentTime, + // 'fetchOriginator' => 'false', + // 'searchStatus' => 'ACTIVE,ACKNOWLEDGED,CLEARED' + // ]); -// if ($alarmResponse->successful()) { -// $alarms = $alarmResponse->json()['data'] ?? []; -// $device->has_alarm = !empty($alarms); // Set to true if any alarms exist -// } else { -// Log::error("Failed to fetch alarms for Device ID: {$device->id}, Error: " . $alarmResponse->body()); -// } + // if ($alarmResponse->successful()) { + // $alarms = $alarmResponse->json()['data'] ?? []; + // $device->has_alarm = !empty($alarms); // Set to true if any alarms exist + // } else { + // Log::error("Failed to fetch alarms for Device ID: {$device->id}, Error: " . $alarmResponse->body()); + // } -// // Fetch telemetry data for the device -// $telemetryResponse = Http::withHeaders([ -// 'accept' => 'application/json', -// 'Authorization' => 'Bearer ' . $bearerToken, -// ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ -// 'useStrictDataTypes' => 'false' -// ]); + // // Fetch telemetry data for the device + // $telemetryResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ + // 'useStrictDataTypes' => 'false' + // ]); -// if (!$telemetryResponse->successful()) { -// Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); -// continue; -// } + // if (!$telemetryResponse->successful()) { + // Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); + // continue; + // } -// $telemetryData = $telemetryResponse->json(); + // $telemetryData = $telemetryResponse->json(); -// $engineName = $telemetryData['Engine_Name'][0]['value'] ?? null; + // $engineName = $telemetryData['Engine_Name'][0]['value'] ?? null; -// // Extract values from telemetry data -// $mechanicalHealthValue1 = isset($telemetryData['MechanicalHealth_value'][0]['value']) -// ? (float) $telemetryData['MechanicalHealth_value'][0]['value'] -// : null; + // // Extract values from telemetry data + // $mechanicalHealthValue1 = isset($telemetryData['MechanicalHealth_value'][0]['value']) + // ? (float) $telemetryData['MechanicalHealth_value'][0]['value'] + // : null; -// $engineEfficiencyValue1 = isset($telemetryData['EngineEfficiency_value'][0]['value']) -// ? (float) $telemetryData['EngineEfficiency_value'][0]['value'] -// : null; + // $engineEfficiencyValue1 = isset($telemetryData['EngineEfficiency_value'][0]['value']) + // ? (float) $telemetryData['EngineEfficiency_value'][0]['value'] + // : null; -// $engineEfficiencyValue4 = isset($telemetryData['EngineEfficiency_valueInHealth'][0]['value']) -// ? (float) $telemetryData['EngineEfficiency_valueInHealth'][0]['value'] -// : null; + // $engineEfficiencyValue4 = isset($telemetryData['EngineEfficiency_valueInHealth'][0]['value']) + // ? (float) $telemetryData['EngineEfficiency_valueInHealth'][0]['value'] + // : null; -// $powerLossValue1 = isset($telemetryData['PowerLoss_value'][0]['value']) -// ? (float) $telemetryData['PowerLoss_value'][0]['value'] -// : null; + // $powerLossValue1 = isset($telemetryData['PowerLoss_value'][0]['value']) + // ? (float) $telemetryData['PowerLoss_value'][0]['value'] + // : null; -// // Default health status -// $healthStatusColor = '#0EC23E'; // Green + // // Default health status + // $healthStatusColor = '#0EC23E'; // Green -// if ($engineName === "Torque") { -// $healthStatusColor = '#0EC23E'; // Green -// } elseif ( -// ($mechanicalHealthValue1 > 0 && $mechanicalHealthValue1 < 31) || -// ($engineEfficiencyValue1 > 0 && $engineEfficiencyValue1 < 31) || -// ($engineEfficiencyValue4 > 0 && $engineEfficiencyValue4 < 31) || -// ($powerLossValue1 > 0 && $powerLossValue1 < 31) -// ) { -// $healthStatusColor = '#EF7F30'; // Red -// } elseif ( -// ($mechanicalHealthValue1 > 30 && $mechanicalHealthValue1 < 71) || -// ($engineEfficiencyValue1 > 30 && $engineEfficiencyValue1 < 71) || -// ($engineEfficiencyValue4 > 30 && $engineEfficiencyValue4 < 71) || -// ($powerLossValue1 > 30 && $powerLossValue1 < 71) -// ) { -// $healthStatusColor = '#FFC164'; // Yellow -// } + // if ($engineName === "Torque") { + // $healthStatusColor = '#0EC23E'; // Green + // } elseif ( + // ($mechanicalHealthValue1 > 0 && $mechanicalHealthValue1 < 31) || + // ($engineEfficiencyValue1 > 0 && $engineEfficiencyValue1 < 31) || + // ($engineEfficiencyValue4 > 0 && $engineEfficiencyValue4 < 31) || + // ($powerLossValue1 > 0 && $powerLossValue1 < 31) + // ) { + // $healthStatusColor = '#EF7F30'; // Red + // } elseif ( + // ($mechanicalHealthValue1 > 30 && $mechanicalHealthValue1 < 71) || + // ($engineEfficiencyValue1 > 30 && $engineEfficiencyValue1 < 71) || + // ($engineEfficiencyValue4 > 30 && $engineEfficiencyValue4 < 71) || + // ($powerLossValue1 > 30 && $powerLossValue1 < 71) + // ) { + // $healthStatusColor = '#FFC164'; // Yellow + // } -// $device->health_status = "
"; -// } + // $device->health_status = ""; + // } -// return response()->json($user); -// } catch (Exception $e) { -// Log::error('Error fetching telemetry data: ' . $e->getMessage()); -// return response()->json(['error' => 'Failed to fetch data'], 500); -// } -// } + // return response()->json($user); + // } catch (Exception $e) { + // Log::error('Error fetching telemetry data: ' . $e->getMessage()); + // return response()->json(['error' => 'Failed to fetch data'], 500); + // } + // } -public function index() + + //original + // public function index() + // { + // try { + // $token = readHeaderToken(); + + // // Fetch user with assets and device counts + // $user = User::with(['assets.devices']) + // ->withCount([ + // 'assets as active_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 1); + // }); + // }, + // 'assets as inactive_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 0); + // }); + // } + // ]) + // ->where('id', $token['sub']) + // ->first(); + + // if (!$user) { + // return response()->json(['error' => 'User not found'], 404); + // } + + // $bearerToken = $this->adminService->getToken(); + // $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); + + // foreach ($user->assets->flatMap->devices as $device) { + // $device->health_status = null; + // $device->online = null; + // $device->has_alarm = false; + + // // 1. First check if device exists in ThingsBoard + // $deviceCheckResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/device/{$device->id}"); + + // if (!$deviceCheckResponse->successful()) { + // Log::warning("Device not found in ThingsBoard: {$device->id}"); + // continue; // Skip this device + // } + + // // Fetch device details from API using customer_id + // $deviceResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/customer/{$device->customer_id}/deviceInfos", [ + // 'pageSize' => 100, + // 'page' => 0 + // ]); + + // if (!$deviceResponse->successful()) { + // Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body()); + // continue; + // } + + // $deviceData = collect($deviceResponse->json()['data'] ?? []); + // $matchingDevice = $deviceData->firstWhere('id.id', $device->id); + + // // Set online status + // $device->online = $matchingDevice['active'] ?? null; + + // // Fetch alarm data for the device (last 24 hours) + // $twentyFourHoursAgo = (time() - 86400) * 1000; + // $currentTime = time() * 1000; + + // // Fixed: Use separate API calls for each alarm status + // $alarmStatuses = ['ACTIVE', 'ACKNOWLEDGED', 'CLEARED']; + // $hasAlarm = false; + + // foreach ($alarmStatuses as $status) { + // $alarmResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/alarm/DEVICE/{$device->id}", [ + // 'pageSize' => 100, + // 'page' => 0, + // 'startTime' => $twentyFourHoursAgo, + // 'endTime' => $currentTime, + // 'fetchOriginator' => 'false', + // 'searchStatus' => $status + // ]); + + // if ($alarmResponse->successful()) { + // $alarms = $alarmResponse->json()['data'] ?? []; + // if (!empty($alarms)) { + // $hasAlarm = true; + // break; // No need to check other statuses if we found an alarm + // } + // } else { + // Log::error("Failed to fetch $status alarms for Device ID: {$device->id}, Error: " . $alarmResponse->body()); + // } + // } + + // $device->has_alarm = $hasAlarm; + + // // Fetch telemetry data for the device + // $telemetryResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ + // 'useStrictDataTypes' => 'false' + // ]); + + // if (!$telemetryResponse->successful()) { + // Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); + // continue; + // } + + // $telemetryData = $telemetryResponse->json(); + + // $engineName = $telemetryData['Engine_Name'][0]['value'] ?? null; + + // // Extract values from telemetry data + // $mechanicalHealthValue1 = isset($telemetryData['MechanicalHealth_value'][0]['value']) + // ? (float) $telemetryData['MechanicalHealth_value'][0]['value'] + // : null; + + // $engineEfficiencyValue1 = isset($telemetryData['EngineEfficiency_value'][0]['value']) + // ? (float) $telemetryData['EngineEfficiency_value'][0]['value'] + // : null; + + // $engineEfficiencyValue4 = isset($telemetryData['EngineEfficiency_valueInHealth'][0]['value']) + // ? (float) $telemetryData['EngineEfficiency_valueInHealth'][0]['value'] + // : null; + + // $powerLossValue1 = isset($telemetryData['PowerLoss_value'][0]['value']) + // ? (float) $telemetryData['PowerLoss_value'][0]['value'] + // : null; + + // // Default health status + // $healthStatusColor = '#0EC23E'; // Green + + // if ($engineName === "Torque") { + // $healthStatusColor = '#0EC23E'; // Green + // } elseif ( + // ($mechanicalHealthValue1 > 0 && $mechanicalHealthValue1 < 31) || + // ($engineEfficiencyValue1 > 0 && $engineEfficiencyValue1 < 31) || + // ($engineEfficiencyValue4 > 0 && $engineEfficiencyValue4 < 31) || + // ($powerLossValue1 > 0 && $powerLossValue1 < 31) + // ) { + // $healthStatusColor = '#EF7F30'; // Red + // } elseif ( + // ($mechanicalHealthValue1 > 30 && $mechanicalHealthValue1 < 71) || + // ($engineEfficiencyValue1 > 30 && $engineEfficiencyValue1 < 71) || + // ($engineEfficiencyValue4 > 30 && $engineEfficiencyValue4 < 71) || + // ($powerLossValue1 > 30 && $powerLossValue1 < 71) + // ) { + // $healthStatusColor = '#FFC164'; // Yellow + // } + + // $device->health_status = ""; + // } + + // return response()->json($user); + // } catch (Exception $e) { + // Log::error('Error fetching telemetry data: ' . $e->getMessage()); + // return response()->json(['error' => 'Failed to fetch data'], 500); + // } + // } + + //for engine health + // public function index() + // { + // try { + // $token = readHeaderToken(); + + // // Fetch user with assets and device counts + // $user = User::with(['assets.devices']) + // ->withCount([ + // 'assets as active_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 1); + // }); + // }, + // 'assets as inactive_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 0); + // }); + // } + // ]) + // ->where('id', $token['sub']) + // ->first(); + + // if (!$user) { + // return response()->json(['error' => 'User not found'], 404); + // } + + // $bearerToken = $this->adminService->getToken(); + // $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); + + // foreach ($user->assets->flatMap->devices as $device) { + // $device->celebration_message = null; + // $device->celebration_icon = null; + + // // Fetch telemetry data + // $telemetryResponse = Http::withHeaders([ + // 'accept' => 'application/json', + // 'Authorization' => 'Bearer ' . $bearerToken, + // ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ + // 'useStrictDataTypes' => 'false' + // ]); + + // if (!$telemetryResponse->successful()) { + // Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); + // continue; + // } + + // $telemetryData = $telemetryResponse->json(); + // $daysInMonth = now()->daysInMonth; + + // // Calculate averages + // $mechanicalHealthAvg = collect($telemetryData['MechanicalHealth_valueInPercent'] ?? []) + // ->pluck('value')->map(fn($v) => (float)$v)->avg(); + // $engineEfficiencyAvg = collect($telemetryData['EngineEfficiency_valueInPercent'] ?? []) + // ->pluck('value')->map(fn($v) => (float)$v)->avg(); + // $powerLossAvg = collect($telemetryData['PowerLoss_value'] ?? []) + // ->pluck('value')->map(fn($v) => (float)$v)->avg(); + + // // Check conditions for celebration message + // if ($mechanicalHealthAvg > 70 || $engineEfficiencyAvg > 70 || $powerLossAvg > 70) { + // $device->celebration_icon = '🎉'; + // if ($device->type === 'Engine Health') { + // $device->celebration_message = 'Excellent Engine Health!'; + // } elseif ($device->type === 'Combustion Condition') { + // $device->celebration_message = 'Great Combustion Condition!'; + // } elseif ($device->type === 'Increase in Fuel Consumption') { + // $device->celebration_message = 'Increase in Fuel Consumption Efficiency!'; + // } else { + // $device->celebration_message = 'Outstanding Performance!'; + // } + // } + // } + + // return response()->json($user); + // } catch (Exception $e) { + // Log::error('Error fetching telemetry data: ' . $e->getMessage()); + // return response()->json(['error' => 'Failed to fetch data'], 500); + // } + // } + + + //for type engine and steamtubine + + // public function index() + // { + // try { + // $token = readHeaderToken(); + + // // Fetch user with assets and device counts + // $user = User::with(['assets.devices']) + // ->withCount([ + // 'assets as active_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 1); + // }); + // }, + // 'assets as inactive_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 0); + // }); + // } + // ]) + // ->where('id', $token['sub']) + // ->first(); + + // 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; + + // foreach ($user->assets as $asset) { + // $asset->celebration_message = null; + // $healthyDevices = []; + + // foreach ($asset->devices as $device) { + // $device->celebration_message = null; + // $device->celebration_icon = null; + + // // Fetch telemetry data for the past 30 days + // $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' + // ]); + + // if (!$telemetryResponse->successful()) { + // Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); + // continue; + // } + + // $telemetryData = $telemetryResponse->json(); + + // // Calculate averages for different parameters + // $parameters = [ + // 'MechanicalHealth_valueInPercent', + // 'EngineEfficiency_valueInPercent', + // 'PowerLoss_value', + // 'RegularityDeviation_valueInPercent', + // 'BearingStatus_valueInPercent', + // 'BladeStatus_valueInPercent', + // 'TurbineCoupling_valueInPercent' + // ]; + + // $averages = []; + // foreach ($parameters as $param) { + // $averages[$param] = collect($telemetryData[$param] ?? []) + // ->pluck('value')->map(fn($v) => (float)$v)->avg(); + // } + + // // Check conditions for celebration message + // if (collect($averages)->filter(fn($avg) => $avg > 70)->isNotEmpty()) { + // $device->celebration_icon = '🎉'; + // $device->celebration_message = "Your device '{$device->name}' has maintained good health for the past 30 days."; + // $healthyDevices[] = $device->name; + // } + // } + + // if (!empty($healthyDevices)) { + // $asset->celebration_message = "Your asset '{$asset->name}' has maintained good health for the past 30 days, along with the following devices: " . implode(", ", $healthyDevices) . "."; + // } + // } + + // return response()->json($user); + // } catch (Exception $e) { + // Log::error('Error fetching telemetry data: ' . $e->getMessage()); + // return response()->json(['error' => 'Failed to fetch data'], 500); + // } + // } + + //for device type + + // public function index() + // { + // try { + // $token = readHeaderToken(); + + // // Fetch user with assets and device counts + // $user = User::with(['assets.devices']) + // ->withCount([ + // 'assets as active_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 1); + // }); + // }, + // 'assets as inactive_devices_count' => function ($query) { + // $query->whereHas('devices', function ($q) { + // $q->where('active', 0); + // }); + // } + // ]) + // ->where('id', $token['sub']) + // ->first(); + + // 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; + + // foreach ($user->assets as $asset) { + // $asset->celebration_message = null; + // $healthyDevices = []; + + // foreach ($asset->devices as $device) { + // $device->celebration_message = null; + // $device->celebration_icon = null; + + // // Fetch telemetry data for the past 30 days + // $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' + // ]); + + // if (!$telemetryResponse->successful()) { + // Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); + // continue; + // } + + // $telemetryData = $telemetryResponse->json(); + + // // Calculate averages for different parameters + // $parameters = [ + // 'RegularityDeviation_valueInPercent', + // 'BearingStatus_valueInPercent', + // 'BladeStatusGas_valueInPercent', + // 'CombustionKit_valueInPercent', + // 'TurbineCoupling_valueInPercent', + // 'MElectromag_valueInPercent', + // 'MStressStability_valueInPercent', + // 'MBearing_valueInPercent', + // 'BearingGlobal_valueInPercent', + // 'GlobalMixed_valueInPercent', + // 'GlobalKurto_valueInPercent', + // '2KMixed_valueInPercent', + // '4KMixed_valueInPercent', + // '8KMixed_valueInPercent' + // ]; + + // $averages = []; + // foreach ($parameters as $param) { + // $averages[$param] = collect($telemetryData[$param] ?? []) + // ->pluck('value')->map(fn($v) => (float)$v)->avg(); + // } + + // // Check conditions for celebration message + // if (collect($averages)->filter(fn($avg) => $avg > 70)->isNotEmpty()) { + // $device->celebration_icon = '🎉'; + // $device->celebration_message = "Your device '{$device->name}' has maintained good health for the past 30 days."; + // $healthyDevices[] = $device->name; + // } + // } + + // if (!empty($healthyDevices)) { + // $asset->celebration_message = "Your asset '{$asset->name}' has maintained good health for the past 30 days, along with the following devices: " . implode(", ", $healthyDevices) . "."; + // } + // } + + // return response()->json($user); + // } catch (Exception $e) { + // Log::error('Error fetching telemetry data: ' . $e->getMessage()); + // return response()->json(['error' => 'Failed to fetch data'], 500); + // } + // } + + public function index() { try { $token = readHeaderToken(); @@ -318,133 +762,80 @@ public function index() $bearerToken = $this->adminService->getToken(); $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); + $thirtyDaysAgo = now()->subDays(30)->timestamp * 1000; + $currentTime = now()->timestamp * 1000; - foreach ($user->assets->flatMap->devices as $device) { - $device->health_status = null; - $device->online = null; - $device->has_alarm = false; + // Define device types and their respective parameters + $deviceParameters = [ + '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'], + 'Coupling/Alignment' => ['TurbineCoupling_valueInPercent'], + 'Electromagnetic Stress' => ['MElectromag_valueInPercent'], + 'Stability' => ['MStressStability_valueInPercent'], + 'Bearing' => ['MBearing_valueInPercent'], + 'Mechanical Health' => ['BearingGlobal_valueInPercent', 'MechanicalHealth_valueInPercent'], + 'Global(Umbalance/Alignment/Loosness)' => ['GlobalMixed_valueInPercent'], + 'Shock Index' => ['GlobalKurto_valueInPercent'], + 'Shaft/Clearance' => ['2KMixed_valueInPercent'], + 'Bearings' => ['4KMixed_valueInPercent'], + 'Friction' => ['8KMixed_valueInPercent'], + 'Engine Health' => ['MechanicalHealth_valueInPercent'], + 'Combustion Condition' => ['EngineEfficiency_valueInPercent'], + 'Increase in Fuel Consumption' => ['PowerLoss_value'] + ]; - // 1. First check if device exists in ThingsBoard - $deviceCheckResponse = Http::withHeaders([ - 'accept' => 'application/json', - 'Authorization' => 'Bearer ' . $bearerToken, - ])->get("$apiBaseUrl/api/device/{$device->id}"); + foreach ($user->assets as $asset) { + $asset->celebration_message = null; + $healthyDevices = []; - if (!$deviceCheckResponse->successful()) { - Log::warning("Device not found in ThingsBoard: {$device->id}"); - continue; // Skip this device - } + foreach ($asset->devices as $device) { + $device->celebration_message = null; + $device->celebration_icon = null; - // Fetch device details from API using customer_id - $deviceResponse = Http::withHeaders([ - 'accept' => 'application/json', - 'Authorization' => 'Bearer ' . $bearerToken, - ])->get("$apiBaseUrl/api/customer/{$device->customer_id}/deviceInfos", [ - 'pageSize' => 100, - 'page' => 0 - ]); - - if (!$deviceResponse->successful()) { - Log::error("Failed to fetch device info for Customer ID: {$device->customer_id}, Error: " . $deviceResponse->body()); - continue; - } - - $deviceData = collect($deviceResponse->json()['data'] ?? []); - $matchingDevice = $deviceData->firstWhere('id.id', $device->id); - - // Set online status - $device->online = $matchingDevice['active'] ?? null; - - // Fetch alarm data for the device (last 24 hours) - $twentyFourHoursAgo = (time() - 86400) * 1000; - $currentTime = time() * 1000; - - // Fixed: Use separate API calls for each alarm status - $alarmStatuses = ['ACTIVE', 'ACKNOWLEDGED', 'CLEARED']; - $hasAlarm = false; - - foreach ($alarmStatuses as $status) { - $alarmResponse = Http::withHeaders([ + // Fetch telemetry data for the past 30 days + $telemetryResponse = Http::withHeaders([ 'accept' => 'application/json', 'Authorization' => 'Bearer ' . $bearerToken, - ])->get("$apiBaseUrl/api/alarm/DEVICE/{$device->id}", [ - 'pageSize' => 100, - 'page' => 0, - 'startTime' => $twentyFourHoursAgo, - 'endTime' => $currentTime, - 'fetchOriginator' => 'false', - 'searchStatus' => $status + ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ + 'startTs' => $thirtyDaysAgo, + 'endTs' => $currentTime, + 'useStrictDataTypes' => 'false' ]); - if ($alarmResponse->successful()) { - $alarms = $alarmResponse->json()['data'] ?? []; - if (!empty($alarms)) { - $hasAlarm = true; - break; // No need to check other statuses if we found an alarm - } - } else { - Log::error("Failed to fetch $status alarms for Device ID: {$device->id}, Error: " . $alarmResponse->body()); + if (!$telemetryResponse->successful()) { + Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); + continue; + } + + $telemetryData = $telemetryResponse->json(); + + // Identify device type and related parameters + $deviceType = $device->type ?? 'Unknown'; + $parameters = $deviceParameters[$deviceType] ?? []; + + $averages = []; + foreach ($parameters as $param) { + $averages[$param] = collect($telemetryData[$param] ?? []) + ->pluck('value')->map(fn($v) => (float)$v)->avg(); + } + + Log::info("Device ID: {$device->id}, Type: {$deviceType}, Averages: " . json_encode($averages)); + + // Check conditions for celebration message + if (collect($averages)->filter(fn($avg) => $avg > 70)->isNotEmpty()) { + $device->celebration_icon = '🎉'; + $device->celebration_message = "Your device '{$device->name}' has maintained good health for the past 30 days."; + $healthyDevices[] = $device->name; + Log::info("Celebration Assigned: Device {$device->name} - Message: {$device->celebration_message}, Icon: {$device->celebration_icon}"); } } - $device->has_alarm = $hasAlarm; - - // Fetch telemetry data for the device - $telemetryResponse = Http::withHeaders([ - 'accept' => 'application/json', - 'Authorization' => 'Bearer ' . $bearerToken, - ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ - 'useStrictDataTypes' => 'false' - ]); - - if (!$telemetryResponse->successful()) { - Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); - continue; + if (!empty($healthyDevices)) { + $asset->celebration_message = "Your asset '{$asset->name}' has maintained good health for the past 30 days, along with the following devices: " . implode(", ", $healthyDevices) . "."; + Log::info("Asset Celebration Assigned: Asset {$asset->name} - Message: {$asset->celebration_message}"); } - - $telemetryData = $telemetryResponse->json(); - - $engineName = $telemetryData['Engine_Name'][0]['value'] ?? null; - - // Extract values from telemetry data - $mechanicalHealthValue1 = isset($telemetryData['MechanicalHealth_value'][0]['value']) - ? (float) $telemetryData['MechanicalHealth_value'][0]['value'] - : null; - - $engineEfficiencyValue1 = isset($telemetryData['EngineEfficiency_value'][0]['value']) - ? (float) $telemetryData['EngineEfficiency_value'][0]['value'] - : null; - - $engineEfficiencyValue4 = isset($telemetryData['EngineEfficiency_valueInHealth'][0]['value']) - ? (float) $telemetryData['EngineEfficiency_valueInHealth'][0]['value'] - : null; - - $powerLossValue1 = isset($telemetryData['PowerLoss_value'][0]['value']) - ? (float) $telemetryData['PowerLoss_value'][0]['value'] - : null; - - // Default health status - $healthStatusColor = '#0EC23E'; // Green - - if ($engineName === "Torque") { - $healthStatusColor = '#0EC23E'; // Green - } elseif ( - ($mechanicalHealthValue1 > 0 && $mechanicalHealthValue1 < 31) || - ($engineEfficiencyValue1 > 0 && $engineEfficiencyValue1 < 31) || - ($engineEfficiencyValue4 > 0 && $engineEfficiencyValue4 < 31) || - ($powerLossValue1 > 0 && $powerLossValue1 < 31) - ) { - $healthStatusColor = '#EF7F30'; // Red - } elseif ( - ($mechanicalHealthValue1 > 30 && $mechanicalHealthValue1 < 71) || - ($engineEfficiencyValue1 > 30 && $engineEfficiencyValue1 < 71) || - ($engineEfficiencyValue4 > 30 && $engineEfficiencyValue4 < 71) || - ($powerLossValue1 > 30 && $powerLossValue1 < 71) - ) { - $healthStatusColor = '#FFC164'; // Yellow - } - - $device->health_status = ""; } return response()->json($user); @@ -453,4 +844,5 @@ public function index() return response()->json(['error' => 'Failed to fetch data'], 500); } } + } diff --git a/app/Http/Controllers/AlarmControllerCommon.php b/app/Http/Controllers/AlarmControllerCommon.php index 7d51531..5f222f5 100644 --- a/app/Http/Controllers/AlarmControllerCommon.php +++ b/app/Http/Controllers/AlarmControllerCommon.php @@ -12,6 +12,7 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use App\Models\User; +use App\Services\AdminService; use Tymon\JWTAuth\Facades\JWTAuth; class AlarmControllerCommon extends Controller @@ -154,6 +155,59 @@ class AlarmControllerCommon extends Controller } } + public function clearAlarmById($id) + { + try { + $token = app(AdminService::class)->getToken(); // Fetch cached token + $url = env('THINGSBOARD_URL') . "/api/alarm/{$id}"; + + // Fetch the alarm details first + $getResponse = Http::withHeaders([ + 'X-Authorization' => 'Bearer ' . $token, + 'accept' => 'application/json', + ])->get($url); + + if (!$getResponse->successful()) { + return jsonResponseWithErrorMessage('Failed to fetch alarm: ' . $getResponse->body(), $getResponse->status()); + } + + $alarmData = $getResponse->json(); + + if ($alarmData['cleared'] ?? false) { + return jsonResponseWithSuccessMessage('Alarm is already cleared', [ + 'id' => $alarmData['id']['id'] ?? $id, + 'cleared' => true, + 'clearTs' => $alarmData['clearTs'] ?? null, + 'status' => $alarmData['status'] ?? 'UNKNOWN' + ]); + } + + // Clear the alarm + $clearUrl = env('THINGSBOARD_URL') . "/api/alarm/{$id}/clear"; + $clearResponse = Http::withHeaders([ + 'X-Authorization' => 'Bearer ' . $token, + 'accept' => 'application/json', + ])->post($clearUrl); + + if ($clearResponse->successful()) { + $clearData = $clearResponse->json(); + + return jsonResponseWithSuccessMessage('Alarm cleared successfully', [ + 'id' => $clearData['id']['id'] ?? $id, + 'cleared' => $clearData['cleared'] ?? true, + 'clearTs' => $clearData['clearTs'] ?? now()->timestamp, + 'status' => $clearData['status'] ?? 'CLEARED' + ]); + } + + return jsonResponseWithErrorMessage('Failed to clear alarm: ' . $clearResponse->body(), $clearResponse->status()); + } catch (\Exception $e) { + Log::error('Error clearing alarm: ' . $e->getMessage()); + return jsonResponseWithErrorMessage('An error occurred: ' . $e->getMessage(), 500); + } + } + + public function filterAlarm(Request $request) { @@ -305,5 +359,4 @@ class AlarmControllerCommon extends Controller 'message' => $alert ? 'Alarm conditions met!' : 'No matching alarms found.' ]); } - } diff --git a/routes/admin_api.php b/routes/admin_api.php index d3ec6aa..a9607c7 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -60,6 +60,9 @@ Route::post('/update-device-profile-master/{deviceId}', [DeviceProfileMasterCont Route::post('/alarm/create-or-update', [AlarmControllerCommon::class, 'createOrUpdateAlarm'])->name('alarm.create-or-update'); Route::get('/alarm/{id}', [AlarmControllerCommon::class, 'getAlarmById'])->name('get.alarm'); Route::post('/alarm/ack/{id}', [AlarmControllerCommon::class, 'acknowledgeAlarmById'])->name('ack.alarm'); +Route::post('/alarm/filter', [AlarmControllerCommon::class, 'filterAlarm'])->name('alarm.filter'); +Route::post('/alarm/clear/{id}', [AlarmControllerCommon::class, 'clearAlarmById'])->name('clear.alarm'); + //******************************************************* Rule Chain API ******************************************************** Route::get('/rule-chains', [RuleChainController::class, 'getRuleChainList'])->name('list.RuleChain');