diff --git a/app/Http/Controllers/APIS/CustomerApi/CustomerDeviceInfoController.php b/app/Http/Controllers/APIS/CustomerApi/CustomerDeviceInfoController.php index 4d9f01d..d868bdd 100644 --- a/app/Http/Controllers/APIS/CustomerApi/CustomerDeviceInfoController.php +++ b/app/Http/Controllers/APIS/CustomerApi/CustomerDeviceInfoController.php @@ -61,7 +61,6 @@ class CustomerDeviceInfoController extends Controller try { $data = []; - // ✅ Check Local Database $customer = Customer::with('users.assets.devices')->findOrFail($customerId); foreach ($customer->users as $user) { diff --git a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php new file mode 100644 index 0000000..b5dbeb3 --- /dev/null +++ b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php @@ -0,0 +1,59 @@ +customerInfoService = $customerInfoService; + } + + public function telemetryData($assetId) + { + // Fetch devices with asset and telemetry keys + device profile + $devices = Device::with(['asset', 'timeseriesKeys.deviceProfile']) + ->where('asset_id', $assetId) + ->get(); + + if ($devices->isEmpty()) { + return response()->json(['error' => 'No devices found for the asset'], 404); + } + + $telemetryData = []; + + // Set start and end timestamps + $startTs = now()->subHours(1)->timestamp * 1000; + $endTs = now()->timestamp * 1000; + + // Fetch telemetry data from ThingsBoard + $thingsBoardData = $this->customerInfoService->getTelemetryData($devices, $startTs, $endTs); + + foreach ($devices as $device) { + $deviceToken = $device->token; // Use token + + // Find telemetry data by token + $telemetry = collect($thingsBoardData) + ->firstWhere('device_token', $deviceToken); + + $telemetryData[] = [ + 'device_name' => $device->name, + 'telemetry' => $telemetry['telemetry'] ?? [], + ]; + } + + return response()->json([ + 'telemetry' => $telemetryData + ]); + } + +} diff --git a/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php b/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php index 3707d57..3b01f91 100644 --- a/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php +++ b/app/Http/Controllers/APIS/CustomerApi/UserAssetLinkController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\APIS\CustomerApi; use App\Http\Controllers\Controller; +use App\Models\Asset; use App\Models\User; use App\Models\UserAssetLink; use Illuminate\Http\Request; @@ -16,26 +17,47 @@ class UserAssetLinkController extends Controller public function index() { - $token = readHeaderToken(); + // $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(); + // $userAssetLinks = UserAssetLink::with(['user', 'asset.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(); - return response()->json($user); + // return response()->json($userAssetLinks); + +$token = readHeaderToken(); + +$userAssetLinks = UserAssetLink::with(['user', 'asset.devices']) +->withCount([ + 'asset as active_devices_count' => function ($query) { + $query->whereHas('devices', function ($q) { + $q->where('active', 1); + }); + }, + 'asset as inactive_devices_count' => function ($query) { + $query->whereHas('devices', function ($q) { + $q->where('active', 0); + }); } +]) +->get(); +return response()->json($userAssetLinks) +->withHeaders([ + 'Authorization' => "Bearer $token" +]); } +} diff --git a/app/Models/Device.php b/app/Models/Device.php index 22bef8f..6e6734c 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -13,39 +13,32 @@ class Device extends Model protected $fillable = [ 'id', - 'entity_type', - 'created_time', - 'tenant_id', - 'customer_id', 'name', 'asset_id', 'type', - 'label', 'device_profile_id', - 'firmware_id', - 'software_id', - 'external_id', + 'asset_id', + 'tenant_id', + 'customer_id', + 'label', 'version', 'active', 'additional_info', 'device_data', ]; - protected $casts = [ - 'id' => 'string', - 'tenant_id' => 'string', - 'customer_id' => 'string', - 'device_profile_id' => 'string', - 'firmware_id' => 'string', - 'software_id' => 'string', - 'external_id' => 'string', - 'additional_info' => 'array', - 'device_data' => 'array', - ]; - public function asset() { return $this->belongsTo(Asset::class, 'asset_id', 'id'); } -} \ No newline at end of file + public function deviceProfile() + { + return $this->belongsTo(DeviceProfileMaster::class, 'device_profile_id', 'id'); + } + + public function timeseriesKeys() + { + return $this->hasMany(TimeseriesKeyMaster::class, 'device_profile_xid', 'device_profile_id'); + } +} diff --git a/app/Models/DeviceProfileMaster.php b/app/Models/DeviceProfileMaster.php index 290177e..d7ff059 100644 --- a/app/Models/DeviceProfileMaster.php +++ b/app/Models/DeviceProfileMaster.php @@ -2,8 +2,8 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; class DeviceProfileMaster extends Model { @@ -14,8 +14,16 @@ class DeviceProfileMaster extends Model protected $fillable = [ 'id', 'name', - + 'description', ]; - public $incrementing = false; // Use UUID as primary key - protected $keyType = 'string'; -} + + public function devices() + { + return $this->hasMany(Device::class, 'device_profile_id', 'id'); + } + + public function timeseriesKeys() + { + return $this->hasMany(TimeseriesKeyMaster::class, 'device_profile_xid', 'id'); + } +} \ No newline at end of file diff --git a/app/Models/TimeseriesKeyMaster.php b/app/Models/TimeseriesKeyMaster.php new file mode 100644 index 0000000..85eed34 --- /dev/null +++ b/app/Models/TimeseriesKeyMaster.php @@ -0,0 +1,31 @@ +belongsTo(DeviceProfileMaster::class, 'device_profile_xid', 'id'); + } + + public function device() + { + return $this->belongsTo(Device::class, 'device_profile_xid', 'device_profile_id'); + } +} \ No newline at end of file diff --git a/app/Services/CustomerInfoService.php b/app/Services/CustomerInfoService.php index 205dc20..cdd447c 100644 --- a/app/Services/CustomerInfoService.php +++ b/app/Services/CustomerInfoService.php @@ -2,9 +2,11 @@ namespace App\Services; +use App\Models\TimeseriesKeyMaster; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use App\Services\AdminService; +use Exception; class CustomerInfoService { @@ -44,6 +46,87 @@ class CustomerInfoService } + public function getTelemetryData($devices, $startTs, $endTs, $limit = 100) + { + try { + // Get ThingsBoard token from AdminService + $token = $this->adminService->getToken(); + + if (!$token) { + Log::error("Failed to authenticate with ThingsBoard."); + return ['error' => 'Authentication failed']; + } + + $baseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); + $telemetryData = []; + + foreach ($devices as $device) { + $deviceToken = $device->token; + + // Include asset_id, device_profile_id, and device name + $assetId = $device->asset_id; + $deviceProfileId = $device->device_profile_id; + $deviceName = $device->name; + + if (!$deviceToken) { + Log::warning("Device token missing for device ID: {$device->id}"); + continue; + } + + $keys = $device->timeseriesKeys->pluck('key_name')->implode(','); + + if (empty($keys)) { + Log::warning("No telemetry keys found for device token: {$deviceToken}"); + continue; + } + + // Make the telemetry API call + $response = Http::withHeaders([ + 'X-Authorization' => "Bearer $token", + 'Accept' => 'application/json', + ])->get("{$baseUrl}/api/plugins/telemetry/DEVICE/{$deviceToken}/values/timeseries", [ + 'keys' => $keys, + 'startTs' => $startTs, + 'endTs' => $endTs, + 'limit' => $limit, + 'useStrictDataTypes' => 'false', + ]); + + if (!$response->successful()) { + Log::error("Failed to fetch telemetry data for device token: {$deviceToken}"); + continue; + } + + $data = $response->json(); + + // Format telemetry data with asset_id, device_profile_id, and name as key + $formattedTelemetry = []; + + foreach ($data as $key => $values) { + foreach ($values as $item) { + $formattedTelemetry[] = [ + 'key' => $key, + 'value' => $item['value'], + 'ts' => $item['ts'] + ]; + } + } + + $telemetryData[] = [ + 'asset_id' => $assetId, + 'device_profile_id' => $deviceProfileId, + 'name' => $deviceName, + 'telemetry' => $formattedTelemetry, + ]; + } + + return $telemetryData; + + } catch (Exception $e) { + Log::error("Error fetching telemetry data: " . $e->getMessage()); + return ['error' => 'Failed to fetch telemetry data']; + } + } diff --git a/routes/admin_api.php b/routes/admin_api.php index eefadfd..8292c3a 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -7,6 +7,8 @@ use App\Http\Controllers\APIS\CustomerApi\DeviceController; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\APIS\AdminApi\AssetadmintController; +use App\Http\Controllers\APIS\AdminApi\TelemetryController; + use App\Http\Controllers\APIS\AdminApi\DeviceProfileMasterController; Route::get('/adminapi', function () { return ('Welcome to admin api routes.'); @@ -36,17 +38,3 @@ Route::get('/users-list', [UsersController::class, 'list'])->name('user_list'); Route::delete('/users-delete/{userId}', [UsersController::class, 'delete']); Route::post('/activate/{id}', [UsersController::class, 'activate'])->name('activate.user'); Route::post('/users-login', [UsersController::class, 'loginUser']); - - - -//******************************************************* Device API******************************************************** -Route::post('/device/create-or-update', [DeviceController::class, 'createOrUpdateDevice'])->name('device.create-or-update'); -Route::get('/device/list', [DeviceController::class, 'listDevices'])->name('device.list'); -Route::delete('/device/delete/{deviceId}', [DeviceController::class, 'deleteDevice'])->name('device.delete'); - - -//******************************************************* Admin DeviceProfileMaster API ******************************************************** -Route::get('/device-profile-master/list', [DeviceProfileMasterController::class, 'deviceprofileMasterList'])->name('deviceMaster.list'); -Route::post('/update-device-profile-master/{deviceId}', [DeviceProfileMasterController::class, 'updateDevice'])->name('update.deviceMaster'); - - diff --git a/routes/customer_api.php b/routes/customer_api.php index 0afe816..7e661c1 100644 --- a/routes/customer_api.php +++ b/routes/customer_api.php @@ -7,6 +7,7 @@ use Tymon\JWTAuth\Facades\JWTAuth; use App\Http\Controllers\APIS\CustomerApi\AuthController; use App\Http\Controllers\APIS\CustomerApi\CustomerDeviceInfoController; +use App\Http\Controllers\APIS\CustomerApi\TelemetryController; Route::get('/customerapi', function () { return ('Welcome to admin api routes.'); @@ -15,6 +16,7 @@ Route::get('/customerapi', function () { Route::post('user-login', [AuthController::class, 'login']); Route::get('/customer-device-info/{customerId}',[CustomerDeviceInfoController::class,'customerDeviceInfo']); +Route::get('/telemetry-data/{assetId}',[TelemetryController::class,'telemetryData']); // Route::post('/user-login', [AuthController::class, 'login']); Route::middleware(['customerApiBasicAuth'])->group(function () {