TKK_E32231477/REED_SWITCH_API_GUIDE.md

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:

  1. Forced Entry - Paksa masuk tanpa ID card
  2. Akses luar jam kerja tanpa ID card yang valid
  3. Durasi pintu terbuka terlalu lama (>180 detik)
  4. Akses tanpa ID card di jam kerja normal
  5. 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:

  1. 📧 Email - Semua alert
  2. 📱 SMS - Priority CRITICAL & HIGH (forced entry, unauthorized)
  3. 🔔 Push Notification - Real-time ke security app
  4. 🔗 Webhook - Ke sistem access control eksternal
  5. 📝 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:

  1. False alarms: Adjust door open duration threshold
  2. ID card not detected: Check RFID reader connection
  3. Missing alerts: Verify notification service configuration
  4. 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