adminService = $adminService; } // 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'); // // Log::info('Devices: ' . json_encode($user->assets->flatMap->devices)); // foreach ($user->assets->flatMap->devices as $device) { // $device->health_status = null; // $device->online = 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); // // Explicitly set online status for all devices // $device->online = $matchingDevice['active'] ?? null; // // 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(); // // Log::info('Telemetry data: ' . json_encode($telemetryData)); // $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); // } // } // public function index() // { // try { // $token = readHeaderToken(); // $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; // $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'], // ]; // foreach ($user->assets as $asset) { // $asset->celebration_message = null; // $asset->celebration_icon = false; // Default to false // $healthyDevices = []; // foreach ($asset->devices as $device) { // $device->celebration_message = null; // $device->celebration_icon = false; // Default to 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' // ]); // if (!$telemetryResponse->successful()) { // Log::error("Failed to fetch telemetry for Device ID: {$device->id}, Error: " . $telemetryResponse->body()); // continue; // } // $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(); // } // if (collect($averages)->filter(fn($avg) => $avg > 70)->isNotEmpty()) { // $device->celebration_icon = true; // Set to true // $device->celebration_message = "Your device '{$device->name}' has maintained good health for the past 30 days."; // $healthyDevices[] = $device->name; // } // } // if (!empty($healthyDevices)) { // $asset->celebration_icon = true; // Set to true // $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(); $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'); $currentDate = now(); $currentMonth = $currentDate->month; $currentYear = $currentDate->year; $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'], ]; foreach ($user->assets as $asset) { $asset->celebration_message = null; $asset->celebration_icon = false; $healthyDevices = []; foreach ($asset->devices as $device) { $device->celebration_icon = false; $device->celebration_message = null; $device->online = null; $device->celebration_message = null; $device->celebration_icon = false; // Default to false $device->health_status = 'green'; // Fetch online status $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); $device->online = $matchingDevice['active'] ?? false; $deviceType = trim($device->type) ?? 'Unknown'; $parameters = $deviceParameters[$deviceType] ?? []; $allParametersHealthy = true; foreach ($parameters as $param) { $allDaysHealthy = true; $daysInMonth = now()->daysInMonth; for ($day = 1; $day <= $daysInMonth; $day++) { $startOfDay = Carbon::create($currentYear, $currentMonth, $day)->startOfDay(); $endOfDay = Carbon::create($currentYear, $currentMonth, $day)->endOfDay(); $dailyResponse = Http::withHeaders([ 'accept' => 'application/json', 'Authorization' => 'Bearer ' . $bearerToken, ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries", [ 'startTs' => $startOfDay->timestamp * 1000, 'endTs' => $endOfDay->timestamp * 1000, 'useStrictDataTypes' => 'false' ]); if (!$dailyResponse->successful()) { Log::error("Failed to fetch daily telemetry for Device ID: {$device->id}, Day: $day, Error: " . $dailyResponse->body()); $allDaysHealthy = false; break; } $dailyData = $dailyResponse->json(); $dailyAvg = collect($dailyData[$param] ?? [])->pluck('value')->map(fn($v) => (float)$v)->avg(); if ($dailyAvg <= 70 || is_null($dailyAvg)) { $allDaysHealthy = false; break; } } if (!$allDaysHealthy) { $allParametersHealthy = false; break; } } // === Fetch telemetry once for alerts === $telemetryResponse = Http::withHeaders([ 'accept' => 'application/json', 'Authorization' => 'Bearer ' . $bearerToken, ])->get("$apiBaseUrl/api/plugins/telemetry/DEVICE/{$device->id}/values/timeseries"); $telemetryData = $telemetryResponse->successful() ? $telemetryResponse->json() : []; // === Alert Logic === $alerts = []; $deviceModel = Device::with([ 'timeseriesKeys' => function ($query) { $query->where(function ($q) { $q->where('display_on_dashboard', true) ->orWhere('display_on_popup', true); }) ->select('id', 'device_profile_xid', 'key_name', 'display_name') ->with(['timeseriesAlert' => function ($query) { $query->select('id', 'timeseries_key_master_xid', 'min_value', 'max_value', 'alert_msg'); }]); } ])->find($device->id); if ($deviceModel) { foreach ($deviceModel->timeseriesKeys as $key) { $keyName = $key->key_name; $dataPoint = $telemetryData[$keyName][0] ?? null; if (!$dataPoint || !isset($dataPoint['value'])) { continue; } $currentValue = (float) $dataPoint['value']; foreach ($key->timeseriesAlert as $alert) { $minValue = $alert->min_value !== null ? (float) $alert->min_value : null; $maxValue = $alert->max_value !== null ? (float) $alert->max_value : null; $isBelowMin = $minValue !== null && $currentValue < $minValue; $isAboveMax = $maxValue !== null && $currentValue > $maxValue; if ($isBelowMin || $isAboveMax) { $alerts[] = $alert->alert_msg; } } } } $device->alert = $alerts; // === Celebration logic === if ($allParametersHealthy && !empty($parameters)) { $device->celebration_icon = true; $device->celebration_message = "Your device '{$device->name}' maintained > 70 average for every parameter on all days of this month."; $healthyDevices[] = $device->name; } } if (!empty($healthyDevices)) { $asset->celebration_icon = true; $asset->celebration_message = "Your asset '{$asset->name}' has healthy devices this month: " . 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); } } }