Files
backend_vib360_laravel/app/Http/Controllers/AlarmControllerCommon.php
2025-05-15 11:55:51 +05:30

362 lines
13 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Services\AlarmService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Exception;
use App\Models\Device;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use App\Services\AdminService;
use Tymon\JWTAuth\Facades\JWTAuth;
class AlarmControllerCommon extends Controller
{
protected $alarmService;
public function __construct(AlarmService $alarmService)
{
$this->alarmService = $alarmService;
}
public function createOrUpdateAlarm(Request $request)
{
try {
$alarmData = [
'type' => $request->type ?? null,
'severity' => $request->severity ?? null,
'acknowledged' => false,
'cleared' => false,
'startTs' => $request->startTs ?? Carbon::now()->timestamp,
'endTs' => $request->endTs ?? Carbon::now()->timestamp,
'details' => $request->details ?? [],
'propagate' => true,
'propagateToOwner' => true,
'propagateToTenant' => true,
'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);
}
}
public function getAlarmById($id)
{
try {
$token = app('App\Services\AdminService')->getToken(); // Fetch cached token
$url = env('THINGSBOARD_URL') . "api/alarm/{$id}";
$response = Http::withHeaders([
'X-Authorization' => 'Bearer ' . $token,
'accept' => 'application/json',
])->get($url);
if ($response->successful()) {
$responseData = $response->json();
$data = $responseData['data'] ?? $responseData ?? [];
if (empty($data)) {
return jsonResponseWithErrorMessage('No data found for the provided ID', 404);
}
$filteredData = [
'originator' => $data['originator'] ?? null,
'severity' => $data['severity'] ?? null,
'startTs' => $data['startTs'] ?? null,
'type' => $data['type'] ?? null,
'status' => $data['status'] ?? null,
'assignee' => $data['assigneeId'] ?? null,
];
return jsonResponseWithSuccessMessage('Alarm data fetched successfully', $filteredData);
}
return jsonResponseWithErrorMessage('Failed to fetch alarm data: ' . $response->body(), $response->status());
} catch (\Exception $e) {
return jsonResponseWithErrorMessage('An error occurred while fetching the alarm: ' . $e->getMessage(), 500);
}
}
public function acknowledgeAlarmById($id)
{
try {
$token = app('App\Services\AdminService')->getToken(); // Fetch cached token0
$url = env('THINGSBOARD_URL') . "api/alarm/{$id}";
$getResponse = Http::withHeaders([
'X-Authorization' => 'Bearer ' . $token,
'accept' => 'application/json',
])->get($url);
if (!$getResponse->successful()) {
return jsonResponseWithErrorMessage('Failed to fetch alarm: ' . $getResponse->body(), $getResponse->status());
}
$alarmData = $getResponse->json();
if ($alarmData['acknowledged'] ?? false) {
return jsonResponseWithSuccessMessage('Alarm is already acknowledged', [
'id' => $alarmData['id']['id'] ?? $id,
'acknowledged' => true,
'ackTs' => $alarmData['ackTs'] ?? null,
'status' => $alarmData['status'] ?? 'UNKNOWN'
]);
}
$ackUrl = env('THINGSBOARD_URL') . "api/alarm/{$id}/ack";
$ackResponse = Http::withHeaders([
'X-Authorization' => 'Bearer ' . $token,
'accept' => 'application/json',
])->post($ackUrl);
if ($ackResponse->successful()) {
$ackData = $ackResponse->json();
return jsonResponseWithSuccessMessage('Alarm acknowledged successfully', [
'id' => $ackData['id']['id'] ?? $id,
'acknowledged' => $ackData['acknowledged'] ?? true,
'ackTs' => $ackData['ackTs'] ?? now()->timestamp,
'status' => $ackData['status'] ?? 'ACTIVE_ACK'
]);
}
return jsonResponseWithErrorMessage('Failed to acknowledge alarm: ' . $ackResponse->body(), $ackResponse->status());
} catch (\Exception $e) {
return jsonResponseWithErrorMessage('An error occurred: ' . $e->getMessage(), 500);
}
}
public function clearAlarmById($id)
{
try {
$token = app(AdminService::class)->getToken(); // Fetch cached token
$url = env('THINGSBOARD_URL') . "api/alarm/{$id}";
// Fetch the alarm details first
$getResponse = Http::withHeaders([
'X-Authorization' => 'Bearer ' . $token,
'accept' => 'application/json',
])->get($url);
if (!$getResponse->successful()) {
return jsonResponseWithErrorMessage('Failed to fetch alarm: ' . $getResponse->body(), $getResponse->status());
}
$alarmData = $getResponse->json();
if ($alarmData['cleared'] ?? false) {
return jsonResponseWithSuccessMessage('Alarm is already cleared', [
'id' => $alarmData['id']['id'] ?? $id,
'cleared' => true,
'clearTs' => $alarmData['clearTs'] ?? null,
'status' => $alarmData['status'] ?? 'UNKNOWN'
]);
}
// Clear the alarm
$clearUrl = env('THINGSBOARD_URL') . "api/alarm/{$id}/clear";
$clearResponse = Http::withHeaders([
'X-Authorization' => 'Bearer ' . $token,
'accept' => 'application/json',
])->post($clearUrl);
if ($clearResponse->successful()) {
$clearData = $clearResponse->json();
return jsonResponseWithSuccessMessage('Alarm cleared successfully', [
'id' => $clearData['id']['id'] ?? $id,
'cleared' => $clearData['cleared'] ?? true,
'clearTs' => $clearData['clearTs'] ?? now()->timestamp,
'status' => $clearData['status'] ?? 'CLEARED'
]);
}
return jsonResponseWithErrorMessage('Failed to clear alarm: ' . $clearResponse->body(), $clearResponse->status());
} catch (\Exception $e) {
Log::error('Error clearing alarm: ' . $e->getMessage());
return jsonResponseWithErrorMessage('An error occurred: ' . $e->getMessage(), 500);
}
}
public function filterAlarm(Request $request)
{
try {
// dd('alarm');
$alarmData = $request->only([
'severity',
'pageSize',
'page',
'startTs',
'endTs',
'deviceId',
'assetId',
'assignId',
]);
$apiResponse = $this->alarmService->filterAlarm($alarmData);
return jsonResponseWithSuccessMessage('Alarm data retrieved 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);
}
}
public function getDeviceAlarms(Request $request)
{
$validator = Validator::make($request->all(), [
'device_id' => 'required|string',
'pageSize' => 'nullable|integer',
'page' => 'nullable|integer',
]);
// Handle validation failure
if ($validator->fails()) {
return response()->json(['error' => $validator->errors()->first()], 400);
}
// Get the device ID from the request
$deviceId = $request->input('device_id');
$pageSize = $request->input('pageSize', 1000);
$page = $request->input('page', 0);
// Fetch ThingsBoard token
$token = $this->alarmService->getToken();
if (!$token) {
return response()->json(['error' => 'Failed to fetch ThingsBoard token'], 401);
}
$baseUrl = env('THINGSBOARD_URL');
// Get timestamps for the past 24 hours
$endTime = now()->timestamp * 1000; // Current time in ms
$startTime = now()->subHours(24)->timestamp * 1000; // 24 hours ago in ms
// Fetch alarms from ThingsBoard API
$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'
]);
// If the request fails, return an error
if (!$response->successful()) {
return response()->json(['error' => 'Failed to fetch alarms'], $response->status());
}
$alarms = $response->json()['data'] ?? [];
// Get the token from the Authorization header
$token = $request->header('Authorization');
if ($token) {
$token = str_replace('Bearer ', '', $token);
// Decode the token
try {
$user = JWTAuth::toUser($token);
} catch (\Exception $e) {
return response()->json(['error' => 'Invalid token'], 401);
}
if (!$user) {
return response()->json(['error' => 'User not found in the token'], 401);
}
// Retrieve the customer_id from the decoded user
$customerId = $user->customer_id;
} else {
return response()->json(['error' => 'Token not provided'], 400);
}
// Alert initialization
$alert = false;
// Retrieve the device data to check if it belongs to the logged-in user's customer_id
$device = Device::find($deviceId);
if (!$device) {
return response()->json(['error' => 'Device not found'], 404);
}
// Check if the device's customer_id matches the logged-in user's customer_id
if ($device->customer_id !== $customerId) {
return response()->json(['error' => 'Device does not belong to the logged-in user\'s customer'], 403);
}
// Get device display name
$deviceDisplayName = $device->display_name;
// Iterate through the alarms to check if any match the criteria
foreach ($alarms as $alarm) {
// Match the device ID with the alarm's originator
$isDeviceMatch = isset($alarm['originator']['id']) && $alarm['originator']['id'] === $deviceId;
// Match the assignee user ID with the logged-in user
$isUserMatch = isset($alarm['assignee']['id']['id']) && $alarm['assignee']['id']['id'] === $user->id;
// Match the alarm type with the device's display name
$isTypeMatch = isset($alarm['type']) && $alarm['type'] === $deviceDisplayName;
// Check if the device, user, and alarm type conditions are met
if ($isDeviceMatch && $isUserMatch && $isTypeMatch) {
$alert = true;
break;
}
}
return response()->json([
'alert' => $alert,
'alarms' => $alarms,
'message' => $alert ? 'Alarm conditions met!' : 'No matching alarms found.'
]);
}
}