From 0d7103ebbe5ac8dd0f885659916fd89bb3cb3265 Mon Sep 17 00:00:00 2001 From: sayliraut Date: Wed, 26 Mar 2025 11:37:58 +0530 Subject: [PATCH] device user list based on customer, login, create alarm --- .../CustomerController.php | 2 +- .../DeviceController.php | 23 ++- .../APIS/AdminApi/LoginController.php | 56 +++++++ .../APIS/AdminApi/UsersController.php | 40 +++-- .../APIS/CustomerApi/TelemetryController.php | 33 +++-- app/Http/Controllers/AlarmController.php | 65 +++++++++ app/Models/Device.php | 5 + app/Models/User.php | 8 +- app/Services/AlarmService.php | 138 ++++++++++++++++++ routes/admin_api.php | 17 ++- 10 files changed, 350 insertions(+), 37 deletions(-) rename app/Http/Controllers/APIS/{CustomerApi => AdminApi}/CustomerController.php (99%) rename app/Http/Controllers/APIS/{CustomerApi => AdminApi}/DeviceController.php (89%) create mode 100644 app/Http/Controllers/APIS/AdminApi/LoginController.php create mode 100644 app/Http/Controllers/AlarmController.php create mode 100644 app/Services/AlarmService.php diff --git a/app/Http/Controllers/APIS/CustomerApi/CustomerController.php b/app/Http/Controllers/APIS/AdminApi/CustomerController.php similarity index 99% rename from app/Http/Controllers/APIS/CustomerApi/CustomerController.php rename to app/Http/Controllers/APIS/AdminApi/CustomerController.php index e48fce1..0ace801 100644 --- a/app/Http/Controllers/APIS/CustomerApi/CustomerController.php +++ b/app/Http/Controllers/APIS/AdminApi/CustomerController.php @@ -1,6 +1,6 @@ getMessage(), 500); } } + + + public function devicelistCustomer($customerId) + { + try { + + $devices = Device::where('customer_id', $customerId)->get(); + + if ($devices->isEmpty()) { + return response()->json(['message' => 'No devices found for this customer ID'], 404); + } + + return jsonResponseWithSuccessMessage('Devices fetched successfully', [ + 'Devices' => $devices + ]); + } catch (Exception $e) { + Log::error("An error occurred in customer device listing: " . $e->getMessage()); + + return jsonResponseWithErrorMessage($e->getMessage(), 500); + } + } } diff --git a/app/Http/Controllers/APIS/AdminApi/LoginController.php b/app/Http/Controllers/APIS/AdminApi/LoginController.php new file mode 100644 index 0000000..b5ea8ae --- /dev/null +++ b/app/Http/Controllers/APIS/AdminApi/LoginController.php @@ -0,0 +1,56 @@ +all(), [ + + 'username' => 'required|string', + 'password' => 'required|string', + ]); + if ($validator->fails()) { + return jsonResponseWithErrorMessage($validator->errors()->first(), 400); + } + + + + $baseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); + + try { + $response = Http::withHeaders([ + 'accept' => 'application/json', + 'Content-Type' => 'application/json', + ])->post("{$baseUrl}/api/auth/login", [ + 'username' => $request->username, + 'password' => $request->password, + ]); + + if ($response->successful()) { + $token = $response->json('token'); + + return jsonResponseWithSuccessMessage(__('Login successful'), $token, 200); + } else { + return response()->json([ + 'message' => __($response->json('message') ?? 'Invalid credentials') + ], 401); + } + } catch (Exception $e) { + Log::error("Login Error: " . $e->getMessage()); + return response()->json([ + 'message' => __('auth.something_went_wrong') + ], 500); + } + } +} diff --git a/app/Http/Controllers/APIS/AdminApi/UsersController.php b/app/Http/Controllers/APIS/AdminApi/UsersController.php index 9f60396..46a3114 100644 --- a/app/Http/Controllers/APIS/AdminApi/UsersController.php +++ b/app/Http/Controllers/APIS/AdminApi/UsersController.php @@ -77,21 +77,21 @@ class UsersController extends Controller $user->last_login_ts = $request->last_login_ts; $user->save(); - $randomToken = Str::random(64); + $randomToken = Str::random(64); - $activationLink = url("/apia/activate/{$user->id}?token={$randomToken}"); + $activationLink = url("/apia/activate/{$user->id}?token={$randomToken}"); - $mail = Mail::to($user->email)->send(new UserCreatedMail($user, $activationLink)); + $mail = Mail::to($user->email)->send(new UserCreatedMail($user, $activationLink)); - return response()->json([ - 'message' => __('auth.data_fetched_successfully'), - 'user_id' => $user->id, - 'activation_link' => $activationLink, - 'token' => $randomToken, - 'data' => $response - ], 200); - } catch (QueryException $e) { + return response()->json([ + 'message' => __('auth.data_fetched_successfully'), + 'user_id' => $user->id, + 'activation_link' => $activationLink, + 'token' => $randomToken, + 'data' => $response + ], 200); + } catch (QueryException $e) { Log::error('Error in creating User ' . $e->getMessage()); return jsonResponseWithErrorMessageApi(__('auth.something went wrong'), 401); } @@ -146,7 +146,6 @@ class UsersController extends Controller 'message' => 'User deleted successfully from ThingsBoard and local database', 'response' => $response ], 200); - } catch (Exception $e) { Log::error('Error in deleting User ' . $e->getMessage()); @@ -259,7 +258,6 @@ class UsersController extends Controller 'message' => 'User activated and password set successfully in Laravel!', 'user_id' => $user->id ], 200); - } catch (ValidationException $e) { Log::error("Validation error for User ID: {$id}. Exception: " . $e->getMessage()); return response()->json([ @@ -267,7 +265,6 @@ class UsersController extends Controller 'message' => 'Validation error.', 'errors' => $e->errors() ], 422); - } catch (\Exception $e) { Log::error("Error activating user ID: {$id}. Exception: " . $e->getMessage()); return response()->json([ @@ -416,8 +413,23 @@ class UsersController extends Controller ], 200); } + public function userlistCustomer($customerId) + { + try { + $users = User::where('customer_id', $customerId)->get(); + if ($users->isEmpty()) { + return response()->json(['message' => 'No users found for this customer ID'], 404); + } + return jsonResponseWithSuccessMessage('users fetched successfully', [ + 'users' => $users + ]); + } catch (Exception $e) { + Log::error("An error occurred in customer user listing: " . $e->getMessage()); + return jsonResponseWithErrorMessage($e->getMessage(), 500); + } + } } diff --git a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php index b4e3672..b5d023e 100644 --- a/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php +++ b/app/Http/Controllers/APIS/CustomerApi/TelemetryController.php @@ -44,22 +44,31 @@ class TelemetryController extends Controller foreach ($devices as $device) { $telemetry = []; - // ✅ Fetch key names from timeseries_key_master associated with the device profile - $keyNames = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id) - ->pluck('key_name') - ->toArray(); + // ✅ Fetch key names along with additional columns from timeseries_key_master + $keysData = TimeseriesKeyMaster::where('device_profile_xid', $device->device_profile_id) + ->where(function ($query) { + $query->where('display_on_dashboard', true) + ->orWhere('display_on_popup', true); + }) + ->get(['key_name', 'display_name', 'display_on_dashboard', 'display_on_popup']); + + $keyNames = $keysData->pluck('key_name')->toArray(); // ✅ Fetch telemetry data $telemetryResponse = $this->customerInfoService->getTelemetryData($device, $keyNames, $startTs, $endTs); + foreach ($keysData as $keyData) { + $keyName = $keyData->key_name; - foreach ($keyNames as $keyName) { if (isset($telemetryResponse[$keyName])) { foreach ($telemetryResponse[$keyName] as $item) { $telemetry[] = [ - 'key_name' => $keyName, - 'timestamp' => $item['ts'] ?? null, - 'value' => $item['value'] ?? null + 'key_name' => $keyName, + 'display_name' => $keyData->display_name, + 'display_on_dashboard' => $keyData->display_on_dashboard, + 'display_on_popup' => $keyData->display_on_popup, + 'timestamp' => $item['ts'] ?? null, + 'value' => $item['value'] ?? null ]; } } @@ -78,12 +87,4 @@ class TelemetryController extends Controller return response()->json(['telemetry' => $response]); } - - - - - - - - } diff --git a/app/Http/Controllers/AlarmController.php b/app/Http/Controllers/AlarmController.php new file mode 100644 index 0000000..a4ae21d --- /dev/null +++ b/app/Http/Controllers/AlarmController.php @@ -0,0 +1,65 @@ +alarmService = $alarmService; + } + + public function createOrUpdateAlarm(Request $request) + { + try { + $alarmData = [ + 'type' => $request->type ?? null, + 'severity' => $request->severity ?? null, + 'acknowledged' => false ?? null, + 'cleared' => $request->cleared ?? Carbon::now()->timestamp, + 'startTs' => $request->startTs ?? Carbon::now()->timestamp, + 'endTs' => $request->endTs ?? Carbon::now()->timestamp, + 'details' => $request->details ?? [], + 'propagate' => $request->propagate ?? false, + 'propagateToOwner' => $request->propagateToOwner ?? false, + 'propagateToTenant' => $request->propagateToTenant ?? false, + 'originator' => $request->originator ?? 1, + 'assigneeId' => $request->assigneeId ?? 1, + + + ]; + + // Handle updating existing alarm + if (!empty($request->id)) { + $alarmData['id'] = $request->id; + } + + // Call Service to create/update device + $apiResponse = $this->alarmService->createOrUpdateAlarm($alarmData); + + + return jsonResponseWithSuccessMessage( + !empty($request->id) ? 'Alarm updated successfully' : 'Alarm created successfully', + ['api_response' => $apiResponse] + ); + } catch (Exception $e) { + Log::error("Error: " . $e->getMessage()); + + $errorResponse = json_decode($e->getMessage(), true); + if (json_last_error() === JSON_ERROR_NONE) { + return jsonResponseWithErrorMessage($errorResponse['message'] ?? 'Something went wrong', 400, $errorResponse); + } + + return jsonResponseWithErrorMessage($e->getMessage(), 500); + } + } +} diff --git a/app/Models/Device.php b/app/Models/Device.php index 83171bb..8e15c96 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -52,4 +52,9 @@ class Device extends Model { return $this->hasMany(TimeseriesKeyMaster::class, 'device_profile_xid', 'device_profile_id'); } + + public function customer() + { + return $this->belongsTo(Customer::class, 'customer_xid', 'id'); + } } diff --git a/app/Models/User.php b/app/Models/User.php index bb21620..2976252 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -20,7 +20,7 @@ class User extends Authenticatable implements JWTSubject public function getJWTIdentifier() { // return $this->getKey(); - return (string) $this->getKey(); + return (string) $this->getKey(); } public function getJWTCustomClaims() @@ -67,4 +67,8 @@ class User extends Authenticatable implements JWTSubject return $this->hasManyThrough(Asset::class, UserAssetLink::class, 'user_id', 'id', 'id', 'asset_id'); } -} \ No newline at end of file + public function customer() + { + return $this->belongsTo(Customer::class, 'customer_id', 'id'); + } +} diff --git a/app/Services/AlarmService.php b/app/Services/AlarmService.php new file mode 100644 index 0000000..849dcb8 --- /dev/null +++ b/app/Services/AlarmService.php @@ -0,0 +1,138 @@ +baseUrl = env('THINGSBOARD_URL', 'http://65.0.131.117:8080'); + $this->username = env('THINGSBOARD_USERNAME', 'tenant1@thingsboard.org'); + $this->password = env('THINGSBOARD_PASSWORD', 'tenant1'); + } + + public function getToken() + { + if (Cache::has('thingsboard_token')) { + return Cache::get('thingsboard_token'); + } + + $response = Http::withHeaders([ + 'accept' => 'application/json', + 'Content-Type' => 'application/json', + ]) + ->post("{$this->baseUrl}/api/auth/login", [ + 'username' => $this->username, + 'password' => $this->password, + ]); + + + if ($response->successful()) { + $token = $response->json('token'); + Cache::put('thingsboard_token', $token, now()->addMinutes(15)); + return $token; + } else { + Log::error("ThingsBoard Authentication Failed: " . $response->body()); + throw new Exception('Unable to authenticate with ThingsBoard: ' . $response->body()); + } + } + + + public function createOrUpdateAlarm(array $data) + { + + $token = $this->getToken(); + + $payload = [ + 'type' => $data['type'] ?? null, + 'severity' => $data['severity'] ?? null, + 'acknowledged' => $data['acknowledged'] ?? null, + 'cleared' => $data['cleared'] ?? Carbon::now()->timestamp, + 'startTs' => $data['startTs'] ?? Carbon::now()->timestamp, + 'endTs' => $data['endTs'] ?? Carbon::now()->timestamp, + 'originator' => [ + 'id' => $data['originator'] ?? null, + 'entityType' => 'DEVICE' + ], + 'assigneeId' => [ + 'id' => $data['assigneeId'] ?? null, + 'entityType' => 'USER' + ], + 'details' => $data['details'] ?? [], + 'propagate' => $data['propagate'] ?? false, + 'propagateToOwner' => $data['propagateToOwner'] ?? false, + + ]; + + + // Optional fields + if (!empty($data['id'])) { + $payload['id'] = [ + 'id' => $data['id'], + 'entityType' => 'ALARM' + ]; + } + + + + $url = "{$this->baseUrl}/api/alarm"; + $method = 'post'; + + $response = Http::withHeaders([ + 'Authorization' => "Bearer $token", + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + ])->post($url, $payload); + + if (!$response->successful()) { + Log::error("API Error Response:", ['body' => $response->body()]); + throw new Exception('API Error: ' . $response->body()); + } + + $apiResponse = $response->json(); + + return $apiResponse; + } + + + + public function deleteDevice(array $data) + { + $token = $this->getToken(); + + + $url = "{$this->baseUrl}/api/device/{$data['deviceId']}"; + + $response = Http::withHeaders([ + 'Authorization' => "Bearer $token", + 'Accept' => 'application/json', + ])->delete($url); + + + + // If response body is empty, assume success + if ($response->status() === 200 && empty($response->body())) { + return ['message' => 'Device deleted successfully']; + } + + if ($response->successful()) { + return $response->json(); + } else { + throw new Exception('Failed to create Device: ' . $response->body()); + Log::info('API Response:', ['response' => $response]); + } + + throw new Exception('Failed to create user: ' . $response->body()); + } +} diff --git a/routes/admin_api.php b/routes/admin_api.php index 581a400..48d73dd 100644 --- a/routes/admin_api.php +++ b/routes/admin_api.php @@ -1,20 +1,26 @@ name('admin.login'); + + Route::post('/asset', [AssetadmintController::class, 'storeAssest'])->name('assest.create'); Route::get('/assets-list', [AssetadmintController::class, 'listAssest'])->name('assest.list'); @@ -38,6 +44,8 @@ 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']); +Route::get('/users/{customer_id}', [UsersController::class, 'userlistCustomer'])->name('usertList.customer'); + @@ -45,6 +53,7 @@ Route::post('/users-login', [UsersController::class, 'loginUser']); 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::post('/device/delete/{deviceId}', [DeviceController::class, 'deleteDevice'])->name('device.delete'); +Route::get('/device/{customer_id}', [DeviceController::class, 'devicelistCustomer'])->name('devicetList.customer'); //******************************************************* Admin DeviceProfileMaster API ******************************************************** @@ -52,3 +61,5 @@ Route::get('/device-profile-master/list', [DeviceProfileMasterController::class, Route::post('/update-device-profile-master/{deviceId}', [DeviceProfileMasterController::class, 'updateDevice'])->name('update.deviceMaster'); +//******************************************************* Alarm API ******************************************************** +Route::post('/alarm/create-or-update', [AlarmController::class, 'createOrUpdateAlarm'])->name('alarm.create-or-update');