841 lines
36 KiB
PHP
841 lines
36 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\APIS\CustomerApi;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Asset;
|
|
use App\Models\Customer;
|
|
use App\Models\Device;
|
|
use App\Models\TimeseriesAlertMessage;
|
|
use App\Models\TimeseriesKeyMaster;
|
|
use App\Models\User;
|
|
use App\Models\UserAssetLink;
|
|
use App\Services\AdminService;
|
|
use App\Services\AlarmService;
|
|
use App\Services\CustomerInfoService;
|
|
use Illuminate\Container\Attributes\DB;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB as FacadesDB;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
class TelemetryController extends Controller
|
|
{
|
|
protected $customerInfoService, $alarmService, $adminService;
|
|
|
|
// public function __construct(CustomerInfoService $customerInfoService)
|
|
// {
|
|
// $this->customerInfoService = $customerInfoService;
|
|
// }
|
|
public function __construct(CustomerInfoService $customerInfoService, AlarmService $alarmService, AdminService $adminService)
|
|
{
|
|
$this->customerInfoService = $customerInfoService;
|
|
$this->alarmService = $alarmService;
|
|
$this->adminService = $adminService;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public function telemetryDataAsset(Request $request)
|
|
// {
|
|
// try {
|
|
// $token = readHeaderToken();
|
|
// $userId = $token['sub'];
|
|
// $customerId = User::where('id', $userId)->value('customer_id');
|
|
|
|
// // 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');
|
|
|
|
// // Verify asset ownership
|
|
// $assetLinkExists = UserAssetLink::where('user_id', $userId)
|
|
// ->where('asset_id', $assetId)
|
|
// ->exists();
|
|
|
|
// if (!$assetLinkExists) {
|
|
// return response()->json([
|
|
// 'error' => 'You are not authorized to access this asset',
|
|
// 'code' => 'UNAUTHORIZED_ACCESS'
|
|
// ], 403);
|
|
// }
|
|
|
|
// // 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
|
|
|
|
// // Get devices with their telemetry keys
|
|
// $devices = Device::with([
|
|
// 'deviceProfile' => function($query) {
|
|
// $query->select(['id', 'name']); // Only select needed fields
|
|
// },
|
|
// '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);
|
|
// }
|
|
|
|
// // Process telemetry data for each device
|
|
// $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
|
|
// $trend = null;
|
|
// if ($startValue > 0) {
|
|
// if ($endValue > $startValue) {
|
|
// $trend = 'upward';
|
|
// } elseif ($endValue < $startValue) {
|
|
// $trend = 'downward';
|
|
// } else {
|
|
// $trend = 'stable';
|
|
// }
|
|
// }
|
|
|
|
// // 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 ?: '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);
|
|
// }
|
|
// }
|
|
|
|
public function telemetryDataAsset(Request $request)
|
|
{
|
|
try {
|
|
$token = readHeaderToken();
|
|
$userId = $token['sub'];
|
|
$customerId = User::where('id', $userId)->value('customer_id');
|
|
|
|
// 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');
|
|
|
|
// Verify asset ownership
|
|
$assetLinkExists = UserAssetLink::where('user_id', $userId)
|
|
->where('asset_id', $assetId)
|
|
->exists();
|
|
|
|
if (!$assetLinkExists) {
|
|
return response()->json([
|
|
'error' => 'You are not authorized to access this asset',
|
|
'code' => 'UNAUTHORIZED_ACCESS'
|
|
], 403);
|
|
}
|
|
|
|
// Set timestamps in milliseconds for database query
|
|
$endTsMs = now()->timestamp * 1000;
|
|
$startTsMs = $endTsMs - (30 * 60 * 1000);
|
|
|
|
// Get devices with their telemetry keys
|
|
$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']);
|
|
}
|
|
])->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);
|
|
}
|
|
|
|
// Process telemetry data for each device
|
|
$response = $devices->map(function ($device) use ($startTsMs, $endTsMs) {
|
|
// Check device active status directly
|
|
$deviceInfoToken = $this->adminService->getToken();
|
|
$isActive = false;
|
|
|
|
if ($deviceInfoToken) {
|
|
$baseUrl = env('THINGSBOARD_URL');
|
|
$deviceInfoResponse = Http::withHeaders([
|
|
'Authorization' => "Bearer $deviceInfoToken",
|
|
'Accept' => 'application/json',
|
|
])->get("$baseUrl/api/device/info/{$device->id}");
|
|
|
|
if ($deviceInfoResponse->successful()) {
|
|
$deviceInfo = $deviceInfoResponse->json();
|
|
$isActive = $deviceInfo['active'] ?? false;
|
|
} else {
|
|
Log::error("Failed to fetch device info for device ID: {$device->id}");
|
|
}
|
|
}
|
|
|
|
$keysData = $device->timeseriesKeys;
|
|
$keyNames = $keysData->pluck('key_name')->toArray();
|
|
|
|
// Only fetch telemetry if device is active
|
|
$startTelemetry = [];
|
|
$endTelemetry = [];
|
|
|
|
if ($isActive) {
|
|
$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, $isActive) {
|
|
$startValue = 0;
|
|
$endValue = 0;
|
|
$timestamp = now()->timestamp;
|
|
$trend = null;
|
|
|
|
if ($isActive) {
|
|
$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 only if device is active
|
|
if ($startValue > 0) {
|
|
if ($endValue > $startValue) {
|
|
$trend = 'upward';
|
|
} elseif ($endValue < $startValue) {
|
|
$trend = 'downward';
|
|
} else {
|
|
$trend = 'stable';
|
|
}
|
|
}
|
|
|
|
// 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 = 'grey';
|
|
if ($isActive) {
|
|
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;
|
|
}
|
|
}
|
|
} else {
|
|
$colorCode = 'green';
|
|
}
|
|
}
|
|
|
|
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' => $isActive ? $endValue : 0,
|
|
'start_value' => $isActive && $startValue > 0 ? $startValue : null,
|
|
'trend' => $trend,
|
|
'alert' => isset($alarmMap[$keyData->key_name]),
|
|
'color_code' => $colorCode,
|
|
];
|
|
})->filter()->values();
|
|
|
|
return [
|
|
'device_id' => (string) $device->id,
|
|
'device_name' => (string) $device->deviceProfile->name,
|
|
'device_profile_name' => (string) $device->deviceProfile->name,
|
|
'asset_id' => (string) $device->asset_id,
|
|
'device_profile_id' => (string) $device->device_profile_id,
|
|
'is_active' => $isActive,
|
|
'telemetry' => $telemetry,
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'telemetry' => $response,
|
|
'time_range' => [
|
|
'startTs' => intval($startTsMs / 1000),
|
|
'endTs' => intval($endTsMs / 1000),
|
|
]
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Telemetry data fetch failed: ' . $e->getMessage());
|
|
return response()->json([
|
|
'error' => 'Failed to fetch telemetry data',
|
|
'code' => 'SERVER_ERROR'
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
private function getDeviceAlarmsForTelemetry($deviceId)
|
|
{
|
|
Log::info("Fetching alarms for device: {$deviceId}");
|
|
|
|
$pageSize = 1000;
|
|
$page = 0;
|
|
|
|
// Fetch ThingsBoard token
|
|
$token = $this->alarmService->getToken();
|
|
if (!$token) {
|
|
Log::error("Failed to fetch ThingsBoard token.");
|
|
return [];
|
|
}
|
|
Log::info("Token fetched successfully.");
|
|
|
|
$baseUrl = env('THINGSBOARD_URL');
|
|
|
|
$endTime = now()->timestamp * 1000; // Current time in ms
|
|
$startTime = now()->subHours(24)->timestamp * 1000; // 24 hours ago in ms
|
|
|
|
Log::info("Time range: Start => {$startTime}, End => {$endTime}");
|
|
|
|
// Fetch alarms from ThingsBoard API
|
|
try {
|
|
$response = Http::withHeaders([
|
|
'Authorization' => "Bearer $token",
|
|
'Accept' => 'application/json',
|
|
])->get("$baseUrl/api/v2/alarms", [
|
|
'statusList' => 'ACTIVE',
|
|
'severityList' => 'CRITICAL,MAJOR,MINOR,WARNING',
|
|
'pageSize' => $pageSize,
|
|
'page' => $page,
|
|
'startTime' => $startTime,
|
|
'endTime' => $endTime,
|
|
'sortProperty' => 'createdTime',
|
|
'sortOrder' => 'DESC',
|
|
'originator' => $deviceId // Filter by device ID
|
|
]);
|
|
|
|
if (!$response->successful()) {
|
|
Log::error("Failed to fetch alarms. Status: " . $response->status());
|
|
return [];
|
|
}
|
|
|
|
// Parse the response
|
|
$alarms = $response->json()['data'] ?? [];
|
|
Log::info("Fetched " . count($alarms) . " alarms for device ID: {$deviceId}");
|
|
|
|
// Map alarms by `type` field
|
|
$alarmMap = [];
|
|
foreach ($alarms as $alarm) {
|
|
if (isset($alarm['type'])) {
|
|
$alarmMap[$alarm['type']] = true;
|
|
}
|
|
}
|
|
|
|
Log::info("Mapped alarm types: ", $alarmMap);
|
|
|
|
return $alarmMap;
|
|
} catch (\Exception $e) {
|
|
Log::error("Error fetching alarms: " . $e->getMessage());
|
|
return [];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// public function telemetryDataDevice(Request $request)
|
|
// {
|
|
// try {
|
|
|
|
// $token = readHeaderToken();
|
|
// if (!$token) {
|
|
// return response()->json([
|
|
// 'success' => false,
|
|
// 'error' => 'Authorization token required'
|
|
// ], 401);
|
|
// }
|
|
|
|
// $validator = Validator::make($request->all(), [
|
|
// 'device_id' => 'required|string',
|
|
// 'startTs' => 'nullable|string',
|
|
// 'endTs' => 'nullable|string',
|
|
// ]);
|
|
|
|
// if ($validator->fails()) {
|
|
// return response()->json([
|
|
// 'success' => false,
|
|
// 'error' => $validator->errors()->first()
|
|
// ], 400);
|
|
// }
|
|
|
|
// $deviceId = $request->input('device_id');
|
|
// $startTs = $request->input('startTs') ?: null;
|
|
// $endTs = $request->input('endTs') ?: null;
|
|
|
|
// try {
|
|
// $deviceWithTelemetry = Device::with([
|
|
// 'deviceProfile',
|
|
// 'timeseriesKeys' => function ($query) {
|
|
// $query->select('key_name', 'display_name', 'device_profile_xid', 'display_on_dashboard','display_on_dashboard');
|
|
// }
|
|
// ])
|
|
// ->where('id', $deviceId)
|
|
// ->firstOrFail();
|
|
|
|
// $telemetryResponse = $this->customerInfoService->getTelemetryDataDevice(
|
|
// $deviceWithTelemetry,
|
|
// $deviceWithTelemetry->timeseriesKeys->pluck('key_name')->toArray(),
|
|
// $startTs,
|
|
// $endTs,
|
|
// $token
|
|
// );
|
|
|
|
// if (!is_array($telemetryResponse)) {
|
|
// throw new \Exception("Invalid telemetry data format received from service");
|
|
// }
|
|
|
|
// $telemetry = collect($telemetryResponse)
|
|
// ->flatMap(function ($items, $keyName) use ($deviceWithTelemetry) {
|
|
// $displayName = $deviceWithTelemetry->timeseriesKeys
|
|
// ->firstWhere('key_name', $keyName)?->display_name ?? $keyName;
|
|
|
|
// return collect($items)->map(function ($item) use ($keyName, $displayName) {
|
|
// return [
|
|
// 'key_name' => $keyName,
|
|
// 'timestamp' => $item['ts'] ?? null,
|
|
// 'value' => $item['value'] ?? null,
|
|
// 'display_name' => $displayName,
|
|
// 'display_on_dashboard'
|
|
// ];
|
|
// });
|
|
// })
|
|
// ->values()
|
|
// ->all();
|
|
|
|
// return response()->json([
|
|
// 'success' => true,
|
|
// 'telemetry' => [
|
|
// 'device_id' => (string) $deviceWithTelemetry->id,
|
|
// 'device_name' => $deviceWithTelemetry->name,
|
|
// 'device_profile_name' => $deviceWithTelemetry->deviceProfile->name,
|
|
// 'device_profile_id' => (string) $deviceWithTelemetry->device_profile_id,
|
|
// 'telemetry_data' => $telemetry,
|
|
// ]
|
|
// ], 200);
|
|
// } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
|
|
// return response()->json([
|
|
// 'success' => false,
|
|
// 'error' => 'Device not found'
|
|
// ], 404);
|
|
// } catch (\Exception $e) {
|
|
// return response()->json([
|
|
// 'success' => false,
|
|
// 'error' => 'Failed to fetch telemetry data',
|
|
// 'details' => config('app.debug') ? $e->getMessage() : null
|
|
// ], 503);
|
|
// }
|
|
// } catch (\Exception $e) {
|
|
// return response()->json([
|
|
// 'success' => false,
|
|
// 'error' => 'Internal server error',
|
|
// 'details' => config('app.debug') ? $e->getMessage() : null
|
|
// ], 500);
|
|
// }
|
|
// }
|
|
|
|
public function telemetryDataDevice(Request $request)
|
|
{
|
|
try {
|
|
$token = readHeaderToken();
|
|
$customerId = User::where('id', $token['sub'])->value('customer_id');
|
|
|
|
Log::info('Telemetry request received', ['request_data' => $request->all()]);
|
|
|
|
$token = readHeaderToken();
|
|
if (!$token) {
|
|
Log::warning('Unauthorized access attempt: Missing token');
|
|
return response()->json([
|
|
'success' => false,
|
|
'error' => 'Authorization token required'
|
|
], 401);
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'device_id' => 'required|string',
|
|
'startTs' => 'nullable|string',
|
|
'endTs' => 'nullable|string',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
Log::error('Validation failed', ['errors' => $validator->errors()]);
|
|
return response()->json([
|
|
'success' => false,
|
|
'error' => $validator->errors()->first()
|
|
], 400);
|
|
}
|
|
|
|
$deviceId = $request->input('device_id');
|
|
$startTs = $request->input('startTs') ?: null;
|
|
$endTs = $request->input('endTs') ?: null;
|
|
|
|
try {
|
|
Log::info('Fetching device telemetry', ['device_id' => $deviceId]);
|
|
|
|
$deviceWithTelemetry = Device::with([
|
|
'deviceProfile',
|
|
'timeseriesKeys' => function ($query) {
|
|
$query->where(function ($q) {
|
|
$q->where('display_on_dashboard', true)
|
|
->orWhere('display_on_popup', true);
|
|
})
|
|
->select('key_name', 'display_name', 'device_profile_xid', 'display_on_dashboard', 'display_on_popup');
|
|
}
|
|
])
|
|
->where('id', $deviceId)
|
|
->where('customer_id', $customerId)
|
|
->firstOrFail();
|
|
|
|
$displayKeys = $deviceWithTelemetry->timeseriesKeys->pluck('key_name')->toArray();
|
|
$deviceProfileName = strtolower($deviceWithTelemetry->deviceProfile->name ?? '');
|
|
|
|
Log::info('Device profile and keys retrieved', [
|
|
'device_profile' => $deviceProfileName,
|
|
'display_keys' => $displayKeys
|
|
]);
|
|
|
|
// Pressure key condition
|
|
$pressureKey = 'Pressure_value';
|
|
$pressureActive = false;
|
|
|
|
$telemetryResponse = $this->customerInfoService->getTelemetryDataDevice(
|
|
$deviceWithTelemetry,
|
|
$displayKeys,
|
|
$startTs,
|
|
$endTs,
|
|
$token
|
|
);
|
|
|
|
if (!is_array($telemetryResponse)) {
|
|
Log::error('Invalid telemetry data format received');
|
|
throw new \Exception("Invalid telemetry data format received from service");
|
|
}
|
|
|
|
// Check if the device has "Gas Engine Profile" or "Engine Profile" in its profile name
|
|
if (
|
|
(strpos($deviceProfileName, 'gas engine profile') !== false || strpos($deviceProfileName, 'engine profile') !== false)
|
|
&& isset($telemetryResponse[$pressureKey])
|
|
&& is_array($telemetryResponse[$pressureKey])
|
|
) {
|
|
foreach ($telemetryResponse[$pressureKey] as $pressureData) {
|
|
if (!empty($pressureData['value']) && floatval($pressureData['value']) > 0) {
|
|
$pressureActive = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Log::info('Telemetry data processed', [
|
|
'pressure_value' => $pressureActive,
|
|
'telemetry_keys' => array_keys($telemetryResponse)
|
|
]);
|
|
|
|
// Filter telemetry data based on display keys
|
|
$filteredResponse = array_intersect_key($telemetryResponse, array_flip($displayKeys));
|
|
|
|
// Add Pressure key if condition is met
|
|
if (isset($telemetryResponse[$pressureKey])) {
|
|
$filteredResponse[$pressureKey] = $telemetryResponse[$pressureKey];
|
|
}
|
|
|
|
$telemetry = collect($filteredResponse)
|
|
->flatMap(function ($items, $keyName) use ($deviceWithTelemetry) {
|
|
$keyData = $deviceWithTelemetry->timeseriesKeys->firstWhere('key_name', $keyName);
|
|
|
|
return collect($items)->map(function ($item) use ($keyName, $keyData) {
|
|
return [
|
|
'key_name' => $keyName,
|
|
'timestamp' => $item['ts'] ?? null,
|
|
'value' => $item['value'] ?? null,
|
|
'display_name' => $keyData->display_name ?? $keyName,
|
|
'display_on_dashboard' => $keyData->display_on_dashboard ?? false,
|
|
'display_on_popup' => $keyData->display_on_popup ?? false
|
|
];
|
|
});
|
|
})
|
|
->values()
|
|
->all();
|
|
|
|
Log::info('Telemetry response successfully generated', ['device_id' => $deviceId]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'telemetry' => [
|
|
'device_id' => (string) $deviceWithTelemetry->id,
|
|
'device_name' => $deviceWithTelemetry->name,
|
|
'device_profile_name' => $deviceWithTelemetry->deviceProfile->name,
|
|
'device_profile_id' => (string) $deviceWithTelemetry->device_profile_id,
|
|
'pressure_value' => $pressureActive, // Updated response
|
|
'telemetry_data' => $telemetry,
|
|
]
|
|
], 200);
|
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
|
|
Log::error('Device not found', ['device_id' => $deviceId]);
|
|
return response()->json([
|
|
'success' => false,
|
|
'error' => 'Device not found'
|
|
], 404);
|
|
} catch (\Exception $e) {
|
|
Log::error('Failed to fetch telemetry data', [
|
|
'device_id' => $deviceId,
|
|
'error' => $e->getMessage()
|
|
]);
|
|
return response()->json([
|
|
'success' => false,
|
|
'error' => 'Failed to fetch telemetry data',
|
|
'details' => config('app.debug') ? $e->getMessage() : null
|
|
], 503);
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::critical('Internal server error', ['error' => $e->getMessage()]);
|
|
return response()->json([
|
|
'success' => false,
|
|
'error' => 'Internal server error',
|
|
'details' => config('app.debug') ? $e->getMessage() : null
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// public function telemetryDataDeviceDiagnostic(Request $request, $deviceId)
|
|
// {
|
|
// $devices = Device::with('deviceProfile')
|
|
// ->where('id', $deviceId)
|
|
// ->get();
|
|
|
|
// if ($devices->isEmpty()) {
|
|
// return response()->json(['error' => 'No devices found'], 404);
|
|
// }
|
|
|
|
// $startTs = $request->has('start_date') ? strtotime($request->start_date) * 1000 : null;
|
|
// $endTs = $request->has('end_date') ? strtotime($request->end_date) * 1000 : null;
|
|
|
|
// $response = [];
|
|
|
|
// foreach ($devices as $device) {
|
|
// $telemetry = [];
|
|
|
|
// $keyNames = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id)
|
|
// ->pluck('key_name', 'display_name')
|
|
// ->toArray();
|
|
|
|
// $telemetryResponse = $this->customerInfoService->getTelemetryDataDeviceDiagonostic($device, $keyNames, $startTs, $endTs);
|
|
|
|
// foreach ($keyNames as $keyName) {
|
|
// if (isset($telemetryResponse[$keyName])) {
|
|
// foreach ($telemetryResponse[$keyName] as $item) {
|
|
// $timestamp = $item['ts'] ?? null;
|
|
|
|
// // ✅ Filter telemetry by timestamp range
|
|
// if ($timestamp && $timestamp >= $startTs && $timestamp <= $endTs) {
|
|
// $telemetry[] = [
|
|
// 'key_name' => $keyName,
|
|
// 'timestamp' => $timestamp,
|
|
// 'start_date' => $startTs,
|
|
// 'end_date' => $endTs,
|
|
// 'value' => $item['value'] ?? null,
|
|
// 'display_name' => $keyName,
|
|
// ];
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// if (!empty($telemetry)) {
|
|
// $response[] = [
|
|
// 'device_id' => (string) $device->id,
|
|
// 'device_name' => $device->name,
|
|
// 'device_profile_name' => (string) $device->deviceProfile->name,
|
|
// 'device_profile_id' => (string) $device->device_profile_id,
|
|
// 'telemetry' => $telemetry,
|
|
// ];
|
|
// }
|
|
// }
|
|
|
|
// return response()->json(['telemetry' => $response]);
|
|
// }
|
|
|
|
// public function telemetryDataDeviceDiagnostic(Request $request, $deviceId)
|
|
// {
|
|
// // Fetch devices
|
|
// $devices = Device::with('deviceProfile')
|
|
// ->where('id', $deviceId)
|
|
// ->get();
|
|
|
|
// if ($devices->isEmpty()) {
|
|
// return response()->json(['error' => 'No devices found'], 404);
|
|
// }
|
|
|
|
// // Get start and end timestamps from request parameters
|
|
// $startTs = $request->has('start_date') ? strtotime($request->start_date) * 1000 : null;
|
|
// $endTs = $request->has('end_date') ? strtotime($request->end_date) * 1000 : null;
|
|
|
|
// if (!$startTs || !$endTs) {
|
|
// return response()->json(['error' => 'Start date and end date are required'], 400);
|
|
// }
|
|
|
|
// $response = [];
|
|
|
|
// foreach ($devices as $device) {
|
|
// $telemetry = [];
|
|
|
|
// $keyNames = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id)
|
|
// ->pluck('key_name', 'display_name')
|
|
// ->toArray();
|
|
|
|
// $telemetryResponse = $this->customerInfoService->getTelemetryDataDeviceDiagonostic($device, $keyNames, $startTs, $endTs);
|
|
|
|
// foreach ($keyNames as $displayName => $keyName) {
|
|
// if (isset($telemetryResponse[$keyName])) {
|
|
// foreach ($telemetryResponse[$keyName] as $item) {
|
|
// $itemTs = $item['timestamp'] ?? null;
|
|
|
|
// // ✅ Filter only telemetry within the date range
|
|
// if ($itemTs >= $startTs && $itemTs <= $endTs) {
|
|
// $telemetry[] = [
|
|
// 'key_name' => $keyName,
|
|
// 'value' => $item['value'] ?? null,
|
|
// 'display_name' => $displayName,
|
|
// 'timestamp' => $itemTs,
|
|
// 'start_date' => $startTs,
|
|
// 'end_date' => $endTs
|
|
// ];
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// if (!empty($telemetry)) {
|
|
// $response[] = [
|
|
// 'device_id' => (string) $device->id,
|
|
// 'device_name' => $device->name,
|
|
// 'device_profile_name' => (string) $device->deviceProfile->name,
|
|
// 'device_profile_id' => (string) $device->device_profile_id,
|
|
// 'telemetry' => $telemetry,
|
|
// ];
|
|
// }
|
|
// }
|
|
|
|
// return response()->json(['telemetry' => $response]);
|
|
// }
|
|
|
|
}
|