16 KiB
16 KiB
🚪 Smart Rack Door Access (Reed Switch) API
Backend API untuk menerima data sensor Reed Switch yang mendeteksi buka tutup pintu dan mengirim notifikasi otomatis jika terdeteksi akses mencurigakan atau tidak sah.
📡 API Endpoints
1. Kirim Data Sensor Reed Switch
POST /api/door-access/data
Content-Type: application/json
{
"device_id": 1,
"door_opened": true,
"access_method": "keycard",
"user_id_card": "EMP-1234",
"duration_seconds": 45,
"door_location": "front_door",
"is_forced_entry": false,
"door_opened_at": "2026-04-28T10:30:00Z",
"door_closed_at": "2026-04-28T10:30:45Z",
"metadata": {
"sensor_type": "Reed_Switch_Magnetic",
"firmware_version": "3.1.0"
}
}
Response Authorized (Jam Kerja + ID Card):
{
"success": true,
"message": "Door access data received successfully",
"data": {
"id": 127,
"door_opened": true,
"access_type": "authorized",
"is_authorized": true,
"is_suspicious": false,
"alert_sent": false,
"priority": "info",
"recorded_at": "2026-04-28T10:30:00Z"
}
}
Response Unauthorized (Alert Triggered):
{
"success": true,
"message": "Door access data received successfully",
"data": {
"id": 128,
"door_opened": true,
"access_type": "forced_entry",
"is_authorized": false,
"is_suspicious": true,
"alert_sent": true,
"priority": "critical",
"recorded_at": "2026-04-28T22:15:00Z"
}
}
2. Ambil Data Door Access Terbaru
GET /api/door-access/readings?device_id=1&limit=50&access_type=unauthorized&door_location=front_door&suspicious=true
Response:
{
"success": true,
"data": [
{
"id": 128,
"device_id": 1,
"door_opened": true,
"is_authorized_access": false,
"access_type": "forced_entry",
"access_method": "force",
"user_id_card": null,
"duration_seconds": 180,
"is_suspicious": true,
"door_location": "front_door",
"is_forced_entry": true,
"door_opened_at": "2026-04-28T22:15:00Z",
"door_closed_at": "2026-04-28T22:18:00Z",
"recorded_at": "2026-04-28T22:15:00Z",
"device": {
"id": 1,
"name": "Reed Switch Pintu Utama",
"location": "Ruang Server"
}
}
],
"count": 1
}
3. Ambil Statistik Door Access
GET /api/door-access/statistics?device_id=1&hours=24
Response:
{
"success": true,
"data": {
"total_access_attempts": 85,
"door_opened_count": 78,
"authorized_count": 65,
"unauthorized_count": 13,
"suspicious_count": 8,
"forced_entry_count": 2,
"authorized_percentage": 76.47,
"suspicious_percentage": 9.41,
"avg_duration": 42.5,
"max_duration": 180,
"latest_access": {
"id": 128,
"access_type": "forced_entry",
"user_id_card": null,
"recorded_at": "2026-04-28T22:15:00Z"
},
"access_types": {
"authorized": 65,
"unauthorized": 8,
"after_hours": 5,
"forced_entry": 2,
"emergency": 3,
"maintenance": 2
},
"door_locations": {
"front_door": 45,
"back_door": 20,
"side_door": 15,
"main_entrance": 5
},
"access_methods": {
"keycard": 60,
"manual": 15,
"force": 2,
"emergency": 3,
"maintenance": 2,
"unknown": 3
}
},
"period_hours": 24
}
4. Test Notifikasi Door Access
POST /api/test-door-access-notification
🚨 Sistem Deteksi & Alert
Tipe Akses:
- authorized: Akses sah dengan ID card dalam jam kerja
- unauthorized: Akses tanpa ID card atau ID tidak valid
- after_hours: Akses di luar jam kerja (07:00-18:00)
- forced_entry: Paksa masuk (CRITICAL ALERT)
- emergency: Akses darurat (diizinkan kapan saja)
- maintenance: Akses maintenance dalam jam kerja
Kondisi Mencurigakan:
- Forced Entry - Paksa masuk tanpa ID card
- Akses luar jam kerja tanpa ID card yang valid
- Durasi pintu terbuka terlalu lama (>180 detik)
- Akses tanpa ID card di jam kerja normal
- ID card tidak valid (format bukan EMP-XXXX)
Jam Kerja (Authorized Time):
- Senin - Jumat: 07:00 - 18:00
- Sabtu - Minggu: Semua akses dianggap after_hours
Lokasi Pintu:
- front_door: Pintu depan (akses utama)
- back_door: Pintu belakang (akses service)
- side_door: Pintu samping (akses sekunder)
- main_entrance: Pintu masuk utama gedung
Metode Akses:
- keycard: Menggunakan kartu akses (paling aman)
- manual: Buka manual dengan kunci
- force: Paksa masuk (trigger alert)
- emergency: Akses darurat
- maintenance: Akses maintenance
- unknown: Metode tidak diketahui
🔔 Sistem Notifikasi
Priority Level:
- critical: Forced entry (paksa masuk)
- high: Unauthorized access, after hours tanpa ID
- medium: Emergency access, suspicious activity
- low: Maintenance access
- info: Authorized access normal
Jenis Notifikasi:
- 📧 Email - Semua alert
- 📱 SMS - Priority CRITICAL & HIGH (forced entry, unauthorized)
- 🔔 Push Notification - Real-time ke security app
- 🔗 Webhook - Ke sistem access control eksternal
- 📝 Security Log - Audit trail lengkap dengan user tracking
Contoh Notifikasi:
🚨 SECURITY BREACH: PAKSA MASUK pada Reed Switch Pintu Utama di front_door
Durasi: 180s. Waktu: 2026-04-28 22:15:00
🚨 DOOR ALERT: Akses unauthorized pada Reed Switch Pintu Utama di front_door tanpa ID
Metode: manual. Durasi: 45s. Waktu: 2026-04-28 22:30:00
📊 Database Schema
door_access_readings table:
- id (bigint, primary key)
- device_id (foreign key to devices)
- door_opened (boolean) - Status pintu terbuka
- is_authorized_access (boolean) - Akses sah/tidak
- access_type (enum) - Tipe akses
- access_method (enum) - Metode akses
- user_id_card (string) - ID card pengguna
- duration_seconds (integer) - Durasi pintu terbuka
- is_suspicious (boolean) - Akses mencurigakan
- door_location (enum) - Lokasi pintu
- is_forced_entry (boolean) - Paksa masuk
- metadata (json) - Data tambahan sensor
- door_opened_at (timestamp) - Waktu pintu dibuka
- door_closed_at (timestamp) - Waktu pintu ditutup
- recorded_at (timestamp) - Waktu pembacaan
- created_at, updated_at
🔌 Integrasi IoT Device
Arduino/ESP32 Example:
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <RFID.h>
int reedSwitchPin = 2;
int rfidReaderPin = 4;
bool doorState = false;
unsigned long doorOpenTime = 0;
String lastIdCard = "";
void setup() {
pinMode(reedSwitchPin, INPUT_PULLUP);
Serial.begin(115200);
// WiFi setup...
// RFID setup...
}
void loop() {
bool currentDoorState = !digitalRead(reedSwitchPin); // Reed switch logic
if (currentDoorState != doorState) {
doorState = currentDoorState;
if (doorState) {
// Door opened
doorOpenTime = millis();
lastIdCard = readRFIDCard(); // Read ID card if available
Serial.println("Door opened, ID: " + lastIdCard);
} else {
// Door closed
unsigned long duration = (millis() - doorOpenTime) / 1000;
sendDoorAccessData(true, lastIdCard, duration, "front_door");
Serial.println("Door closed, data sent");
lastIdCard = "";
}
}
delay(100);
}
String readRFIDCard() {
// Implementasi baca RFID card
// Return format: "EMP-1234" atau "" jika tidak ada
return "EMP-1234"; // Simulasi
}
void sendDoorAccessData(bool opened, String idCard, int duration, String location) {
HTTPClient http;
http.begin("http://your-server.com/api/door-access/data");
http.addHeader("Content-Type", "application/json");
StaticJsonDocument<400> doc;
doc["device_id"] = 1;
doc["door_opened"] = opened;
doc["access_method"] = idCard.length() > 0 ? "keycard" : "manual";
doc["user_id_card"] = idCard.length() > 0 ? idCard : nullptr;
doc["duration_seconds"] = duration;
doc["door_location"] = location;
doc["is_forced_entry"] = (idCard.length() == 0 && duration > 10);
String jsonString;
serializeJson(doc, jsonString);
int httpResponseCode = http.POST(jsonString);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("Response: " + response);
}
http.end();
}
Python Example (Raspberry Pi):
import requests
import json
import time
from datetime import datetime
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
REED_SWITCH_PIN = 18
reader = SimpleMFRC522()
def setup_reed_switch():
GPIO.setmode(GPIO.BCM)
GPIO.setup(REED_SWITCH_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def read_rfid_card():
try:
id, text = reader.read_no_block()
if id:
return f"EMP-{id % 10000:04d}" # Format ke EMP-XXXX
return None
except:
return None
def send_door_access_data(device_id, door_opened, id_card, duration, location):
url = "http://your-server.com/api/door-access/data"
access_method = "keycard" if id_card else "manual"
is_forced = not id_card and duration > 10
data = {
"device_id": device_id,
"door_opened": door_opened,
"access_method": access_method,
"user_id_card": id_card,
"duration_seconds": duration,
"door_location": location,
"is_forced_entry": is_forced,
"metadata": {
"timestamp": datetime.now().isoformat(),
"sensor_type": "Reed_Switch_Magnetic",
"gpio_pin": REED_SWITCH_PIN
}
}
response = requests.post(url, json=data)
return response.json()
def monitor_door_access():
door_open = False
door_open_time = None
current_id_card = None
while True:
# Read reed switch (False = door closed, True = door open)
door_state = not GPIO.input(REED_SWITCH_PIN)
if door_state and not door_open:
# Door just opened
door_open = True
door_open_time = time.time()
current_id_card = read_rfid_card()
print(f"Door opened, ID Card: {current_id_card}")
elif not door_state and door_open:
# Door just closed
door_open = False
duration = int(time.time() - door_open_time) if door_open_time else 0
result = send_door_access_data(1, True, current_id_card, duration, "front_door")
print(f"Door access data sent: {result}")
current_id_card = None
door_open_time = None
time.sleep(0.1)
# Usage
setup_reed_switch()
monitor_door_access()
🧪 Testing API
Test dengan cURL:
# Test authorized access (jam kerja + ID card)
curl -X POST http://localhost:8000/api/door-access/data \
-H "Content-Type: application/json" \
-d '{
"device_id": 1,
"door_opened": true,
"access_method": "keycard",
"user_id_card": "EMP-1234",
"duration_seconds": 30,
"door_location": "front_door"
}'
# Test unauthorized access (tanpa ID card)
curl -X POST http://localhost:8000/api/door-access/data \
-H "Content-Type: application/json" \
-d '{
"device_id": 1,
"door_opened": true,
"access_method": "manual",
"duration_seconds": 60,
"door_location": "back_door"
}'
# Test forced entry (CRITICAL ALERT)
curl -X POST http://localhost:8000/api/door-access/data \
-H "Content-Type: application/json" \
-d '{
"device_id": 1,
"door_opened": true,
"access_method": "force",
"duration_seconds": 180,
"door_location": "front_door",
"is_forced_entry": true
}'
# Get statistics
curl "http://localhost:8000/api/door-access/statistics?device_id=1&hours=24"
# Test door access notification
curl -X POST http://localhost:8000/api/test-door-access-notification
📈 Security Dashboard
Real-time Monitoring:
- Current door status (open/closed)
- Active access attempts
- Unauthorized access count (24h)
- Forced entry alerts
- User access patterns
Access Control Reports:
- Daily access summary by user
- Unauthorized access attempts
- After-hours access log
- Door usage statistics by location
- ID card usage tracking
🔒 Security Features
Smart Access Control:
- ID Card Validation: Format EMP-XXXX validation
- Time-based Rules: Working hours vs after hours
- Duration Monitoring: Alert untuk pintu terbuka terlalu lama
- Forced Entry Detection: Deteksi paksa masuk real-time
- User Tracking: Track akses per ID card
Multi-level Security:
- Immediate: Push notification untuk forced entry
- Escalation: SMS untuk unauthorized access
- Audit Trail: Log lengkap semua akses
- Integration: Webhook ke sistem access control
🚀 Deployment & Configuration
Environment Variables:
# Door Access Settings
DOOR_ACCESS_WEBHOOK_URL=https://your-access-control.com/alerts
WORK_START_HOUR=7
WORK_END_HOUR=18
MAX_DOOR_OPEN_DURATION=180
# ID Card Settings
ID_CARD_FORMAT_REGEX=^EMP-\d{4}$
VALID_ID_CARDS=EMP-1234,EMP-5678,EMP-9012
# Notification settings
SECURITY_EMAIL=security@yourcompany.com
SECURITY_SMS_NUMBER=+6281234567890
Konfigurasi Access Control:
// config/door_access.php
return [
'work_hours' => [
'start' => 7, // 07:00
'end' => 18, // 18:00
'weekdays_only' => true
],
'thresholds' => [
'max_door_open_duration' => 180, // 3 minutes
'suspicious_duration' => 120, // 2 minutes
],
'id_card' => [
'format_regex' => '^EMP-\d{4}$',
'required_for_access' => true
],
'locations' => [
'front_door' => ['priority' => 'high', 'require_id' => true],
'back_door' => ['priority' => 'medium', 'require_id' => true],
'side_door' => ['priority' => 'medium', 'require_id' => false],
'main_entrance' => ['priority' => 'high', 'require_id' => true]
]
];
📞 Troubleshooting
Common Issues:
- False alarms: Adjust door open duration threshold
- ID card not detected: Check RFID reader connection
- Missing alerts: Verify notification service configuration
- Wrong access type: Check working hours configuration
Monitoring Commands:
# Check door access logs
tail -f storage/logs/laravel.log | grep "Door Access"
# Database cleanup
php artisan door-access:cleanup-old-data
# Test access control system
php artisan door-access:test-system
Backend Smart Rack Door Access (Reed Switch) siap digunakan! 🎉
Sistem akan otomatis:
- ✅ Menerima data sensor Reed Switch real-time
- ✅ Mendeteksi akses mencurigakan berdasarkan ID card, waktu, dan metode
- ✅ Membedakan akses sah vs tidak sah
- ✅ Mengirim notifikasi multi-channel untuk security breach
- ✅ Menyimpan audit trail lengkap untuk compliance
- ✅ Menyediakan statistik akses dan laporan keamanan
- ✅ Integrasi mudah dengan sistem access control dan CCTV
- ✅ Support multiple door locations dan access methods