2025-03-11 17:15:41 +05:30
< ? php
2025-03-11 17:52:55 +05:30
namespace App\Http\Controllers\APIS\CustomerApi ;
2025-03-11 17:15:41 +05:30
use App\Http\Controllers\Controller ;
2025-03-24 13:31:06 +05:30
use App\Models\Asset ;
2025-04-08 13:18:08 +05:30
use App\Models\Device ;
2025-03-11 17:52:55 +05:30
use App\Models\User ;
2025-03-11 17:15:41 +05:30
use App\Models\UserAssetLink ;
2025-03-25 11:40:43 +05:30
use App\Services\AdminService ;
2025-03-11 17:15:41 +05:30
use Illuminate\Http\Request ;
2025-03-11 19:44:37 +05:30
use Tymon\JWTAuth\Facades\JWTAuth ;
2025-03-25 11:40:43 +05:30
use Illuminate\Support\Facades\Http ;
2025-03-12 19:19:13 +05:30
use Illuminate\Container\Attributes\Auth ;
use Illuminate\Database\QueryException ;
use Illuminate\Support\Facades\Log ;
2025-03-25 11:40:43 +05:30
use Exception ;
2025-04-08 13:08:54 +05:30
use Illuminate\Support\Carbon ;
2025-03-25 11:40:43 +05:30
2025-03-11 17:15:41 +05:30
class UserAssetLinkController extends Controller
{
2025-03-25 11:40:43 +05:30
private $adminService ;
public function __construct ( AdminService $adminService )
{
$this -> adminService = $adminService ;
}
2025-03-12 19:19:13 +05:30
2025-03-31 19:18:36 +05:30
// public function index()
// {
// try {
// $token = readHeaderToken();
2025-03-18 15:45:21 +05:30
2025-03-31 19:18:36 +05:30
// // 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();
2025-03-18 15:45:21 +05:30
2025-03-31 19:18:36 +05:30
// if (!$user) {
// return response()->json(['error' => 'User not found'], 404);
// }
2025-03-18 15:45:21 +05:30
2025-03-31 19:18:36 +05:30
// $bearerToken = $this->adminService->getToken();
// $apiBaseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080');
2025-03-18 15:45:21 +05:30
2025-03-25 11:40:43 +05:30
2025-03-31 19:18:36 +05:30
// // 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 = "<div style='height: 10px; width: 10px; border-radius: 50%; display: inline-block; margin-left: 10px; background-color: $healthStatusColor'></div>";
// }
// return response()->json($user);
// } catch (Exception $e) {
// Log::error('Error fetching telemetry data: ' . $e->getMessage());
// return response()->json(['error' => 'Failed to fetch data'], 500);
// }
// }
2025-04-08 13:08:54 +05:30
// 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();
2025-03-31 19:18:36 +05:30
2025-04-08 13:08:54 +05:30
// 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);
// }
// }
2025-04-07 12:53:20 +05:30
2025-04-02 20:20:57 +05:30
public function index ()
2025-04-04 12:58:41 +05:30
{
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 );
}
2025-03-28 19:48:29 +05:30
2025-04-04 12:58:41 +05:30
$bearerToken = $this -> adminService -> getToken ();
$apiBaseUrl = env ( 'THINGSBOARD_URL' , 'http://65.0.131.117:8080' );
2025-04-08 13:08:54 +05:30
$currentDate = now ();
$currentMonth = $currentDate -> month ;
$currentYear = $currentDate -> year ;
2025-04-04 12:58:41 +05:30
$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 ;
2025-04-08 13:08:54 +05:30
$asset -> celebration_icon = false ;
2025-04-04 12:58:41 +05:30
$healthyDevices = [];
foreach ( $asset -> devices as $device ) {
2025-04-08 13:18:08 +05:30
$device -> celebration_icon = false ;
2025-04-04 12:58:41 +05:30
$device -> celebration_message = null ;
2025-04-07 12:53:20 +05:30
$device -> online = null ;
2025-04-04 12:58:41 +05:30
$device -> celebration_message = null ;
2025-04-08 13:37:42 +05:30
2025-04-04 12:58:41 +05:30
$device -> celebration_icon = false ; // Default to false
2025-04-08 13:18:08 +05:30
$device -> health_status = 'green' ;
2025-04-07 12:53:20 +05:30
2025-04-08 13:37:42 +05:30
// Fetch online status
2025-04-07 12:53:20 +05:30
$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 ;
2025-04-04 12:58:41 +05:30
$deviceType = trim ( $device -> type ) ? ? 'Unknown' ;
$parameters = $deviceParameters [ $deviceType ] ? ? [];
2025-04-08 13:08:54 +05:30
$allParametersHealthy = true ;
2025-04-04 12:58:41 +05:30
foreach ( $parameters as $param ) {
2025-04-08 13:08:54 +05:30
$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 ;
}
2025-04-04 12:58:41 +05:30
}
2025-04-08 13:37:42 +05:30
// === Fetch telemetry once for alerts ===
2025-04-04 12:58:41 +05:30
$telemetryResponse = Http :: withHeaders ([
'accept' => 'application/json' ,
'Authorization' => 'Bearer ' . $bearerToken ,
2025-04-08 13:37:42 +05:30
]) -> get ( " $apiBaseUrl /api/plugins/telemetry/DEVICE/ { $device -> id } /values/timeseries " );
2025-04-04 12:58:41 +05:30
2025-04-08 13:37:42 +05:30
$telemetryData = $telemetryResponse -> successful () ? $telemetryResponse -> json () : [];
2025-04-04 12:58:41 +05:30
2025-04-08 13:37:42 +05:30
// === Alert Logic ===
$alerts = [];
2025-04-08 13:18:08 +05:30
$deviceModel = Device :: with ([
2025-04-08 13:37:42 +05:30
'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' );
}]);
}
2025-04-08 13:18:08 +05:30
]) -> find ( $device -> id );
if ( $deviceModel ) {
2025-04-08 13:37:42 +05:30
foreach ( $deviceModel -> timeseriesKeys as $key ) {
2025-04-08 13:18:08 +05:30
$keyName = $key -> key_name ;
$dataPoint = $telemetryData [ $keyName ][ 0 ] ? ? null ;
2025-04-08 13:37:42 +05:30
if ( ! $dataPoint || ! isset ( $dataPoint [ 'value' ])) {
continue ;
}
2025-04-08 13:18:08 +05:30
2025-04-08 13:37:42 +05:30
$currentValue = ( float ) $dataPoint [ 'value' ];
2025-04-08 13:18:08 +05:30
2025-04-08 13:37:42 +05:30
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 ;
2025-04-07 12:53:20 +05:30
2025-04-08 13:37:42 +05:30
if ( $isBelowMin || $isAboveMax ) {
$alerts [] = $alert -> alert_msg ;
2025-04-07 12:53:20 +05:30
}
}
2025-04-08 13:37:42 +05:30
}
}
2025-04-04 12:58:41 +05:30
2025-04-08 13:37:42 +05:30
$device -> alert = $alerts ;
// === Celebration logic ===
2025-04-08 13:08:54 +05:30
if ( $allParametersHealthy && ! empty ( $parameters )) {
2025-04-08 13:18:08 +05:30
$device -> celebration_icon = true ;
2025-04-08 13:08:54 +05:30
$device -> celebration_message = " Your device ' { $device -> name } ' maintained > 70 average for every parameter on all days of this month. " ;
2025-04-04 12:58:41 +05:30
$healthyDevices [] = $device -> name ;
}
2025-04-02 20:20:57 +05:30
}
2025-04-04 12:58:41 +05:30
if ( ! empty ( $healthyDevices )) {
2025-04-08 13:18:08 +05:30
$asset -> celebration_icon = true ;
2025-04-08 13:08:54 +05:30
$asset -> celebration_message = " Your asset ' { $asset -> name } ' has healthy devices this month: " . implode ( ', ' , $healthyDevices ) . " . " ;
2025-04-02 20:20:57 +05:30
}
2025-03-31 19:18:36 +05:30
}
2025-04-04 12:58:41 +05:30
return response () -> json ( $user );
} catch ( Exception $e ) {
Log :: error ( 'Error fetching telemetry data: ' . $e -> getMessage ());
return response () -> json ([ 'error' => 'Failed to fetch data' ], 500 );
2025-03-25 11:40:43 +05:30
}
}
2025-04-08 13:37:42 +05:30
2025-03-11 19:05:25 +05:30
}