365 lines
13 KiB
PHP
365 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 {
|
|
|
|
$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.'
|
|
]);
|
|
}
|
|
}
|