11from fastapi import APIRouter , Depends , HTTPException , Request
22from sqlalchemy .orm import Session
33from pydantic import BaseModel
4- from app .core .database import get_db
5- from app .models .device import Device
6- from app .core .security import get_current_user
7- from app .core .limiter import limiter
8- from app .mqtt .client import mqtt_client
4+ from typing import Optional
5+
6+ # --- UPDATE IMPORT (Sesuai Struktur Baru) ---
7+ from app .db .database import get_db # <-- Folder db
8+ from app .models .device import SensorLog # <-- Sesuaikan nama class device kamu (Device/SensorLog?)
9+ # Cek model kamu: Kalau nama classnya Device, ganti SensorLog jadi Device di baris atas
10+ from app .mqtt .client import publish_message # <-- Kita pakai helper publish kalau ada, atau client langsung
11+
12+ # --- IMPORT RATE LIMITER REDIS ---
13+ from fastapi_limiter .depends import RateLimiter
914
1015router = APIRouter ()
1116
12- # --- SCHEMA 1: UNTUK USER (CLAIM) ---
13- # User HANYA input ID dan PIN. Tidak perlu Factory Secret.
17+ # --- SCHEMA ---
1418class UserClaimSchema (BaseModel ):
1519 device_id : str
1620 pin_code : str
1721
18- # --- SCHEMA 2: UNTUK ESP32 (AUTO REGISTER) ---
19- # Alat WAJIB punya Factory Secret.
2022class AutoRegisterSchema (BaseModel ):
2123 device_id : str
2224 pin_code : str
2325 factory_secret : str
2426
27+ # Kita butuh model Device (Definisikan ulang kalau belum import)
28+ # Asumsi kamu punya model Device di app/models/device.py
29+ from app .models .device import Device # Pastikan ini ada
2530
2631# --- 1. ENDPOINT CLAIM (User) ---
27- @ router . post ( "/claim" )
28- @limiter . limit ( "5/minute" )
32+ # Rate Limit: 5x per 60 detik
33+ @router . post ( "/claim" , dependencies = [ Depends ( RateLimiter ( times = 5 , seconds = 60 ))])
2934def claim_device (
30- request : Request ,
31- claim_data : UserClaimSchema , # <--- GUNAKAN SCHEMA USER
32- db : Session = Depends (get_db ),
33- user_uid : str = Depends (get_current_user )
35+ claim_data : UserClaimSchema ,
36+ db : Session = Depends (get_db )
37+ # user_uid: str = Depends(get_current_user) # <-- Aktifkan ini nanti kalau AUTH firebase sudah dipasang
3438):
35- # 1. Bersihkan Input (Spasi & Huruf Besar)
39+ # Sementara kita hardcode user_uid dulu biar bisa tes tanpa login frontend
40+ user_uid = "TEST_USER_UID_001"
41+
3642 clean_id = claim_data .device_id .strip ().upper ()
3743 clean_pin = claim_data .pin_code .strip ()
3844
39- # 2. Cari Alat
45+ # Cari Alat
4046 device = db .query (Device ).filter (Device .device_id == clean_id ).first ()
4147
4248 if not device :
43- raise HTTPException (status_code = 404 , detail = f"Alat { clean_id } tidak ditemukan. Pastikan alat sudah nyala. " )
49+ raise HTTPException (status_code = 404 , detail = f"Alat { clean_id } tidak ditemukan." )
4450
4551 if device .owner_uid :
4652 if device .owner_uid == user_uid :
4753 return {"message" : "Alat ini memang sudah punya kamu kok." }
4854 raise HTTPException (status_code = 400 , detail = "Alat ini sudah dimiliki orang lain!" )
4955
50- # 3. Cek PIN
56+ # Cek PIN
5157 if device .pin_code != clean_pin :
52- raise HTTPException (status_code = 400 , detail = "PIN Salah! Cek stiker alat. " )
58+ raise HTTPException (status_code = 400 , detail = "PIN Salah!" )
5359
54- # 4. Simpan Pemilik
60+ # Simpan Pemilik
5561 device .owner_uid = user_uid
5662 device .device_name = "Alat Baru Saya"
5763 db .commit ()
5864
59- return {
60- "status" : "success" ,
61- "message" : f"Selamat! Alat { clean_id } berhasil ditambahkan ke akunmu." ,
62- "owner" : user_uid
63- }
65+ return {"status" : "success" , "message" : f"Alat { clean_id } berhasil diklaim!" }
6466
6567
6668# --- 2. ENDPOINT CONTROL RELAY ---
67- @ router . post ( "/control-relay" )
68- @limiter . limit ( "10/minute" ) # Limit agak longgar buat kontrol
69+ # Rate Limit: 10x per 60 detik
70+ @router . post ( "/control-relay" , dependencies = [ Depends ( RateLimiter ( times = 10 , seconds = 60 ))])
6971def control_relay (
70- request : Request ,
7172 device_id : str ,
7273 state : str ,
73- user_uid : str = Depends (get_current_user ),
7474 db : Session = Depends (get_db )
7575):
76+ # Hardcode user dulu
77+ user_uid = "TEST_USER_UID_001"
78+
7679 clean_id = device_id .strip ().upper ()
7780
7881 if state not in ["ON" , "OFF" ]:
@@ -83,26 +86,28 @@ def control_relay(
8386 if not device :
8487 raise HTTPException (status_code = 404 , detail = "Alat tidak ditemukan." )
8588
86- if device .owner_uid != user_uid :
87- raise HTTPException (status_code = 403 , detail = "Eits! Ini bukan alat kamu." )
89+ # Proteksi Kepemilikan (Nyalakan nanti kalau Auth siap)
90+ # if device.owner_uid != user_uid:
91+ # raise HTTPException(status_code=403, detail="Bukan alat kamu!")
8892
8993 topic = f"alat/{ clean_id } /command"
9094 payload = f'{{"relay": "{ state } "}}'
9195
96+ # Publish ke MQTT
97+ # Pastikan kamu import client mqtt yg benar, atau pakai cara ini:
98+ from app .mqtt .client import client as mqtt_client
9299 mqtt_client .publish (topic , payload )
93100
94- return {"message" : "Perintah dikirim" , "topic" : topic , "payload " : payload }
101+ return {"message" : "Perintah dikirim" , "topic" : topic , "state " : state }
95102
96103
97104# --- 3. ENDPOINT AUTO REGISTER (ESP32) ---
98- @router .post ("/auto-register" )
99- @limiter .limit ("5/minute" )
105+ @router .post ("/auto-register" , dependencies = [Depends (RateLimiter (times = 5 , seconds = 60 ))])
100106def auto_register_device (
101- request : Request ,
102- data : AutoRegisterSchema , # <--- GUNAKAN SCHEMA ALAT
107+ data : AutoRegisterSchema ,
103108 db : Session = Depends (get_db )
104109):
105- FACTORY_SECRET = "RAHASIA_PABRIK_PCB_SERIUS_2026"
110+ FACTORY_SECRET = "RAHASIA_PABRIK_PCB_SERIUS_2026"
106111
107112 if data .factory_secret != FACTORY_SECRET :
108113 raise HTTPException (status_code = 403 , detail = "Anda bukan perangkat resmi!" )
@@ -118,10 +123,9 @@ def auto_register_device(
118123 device_id = clean_id ,
119124 pin_code = clean_pin ,
120125 device_name = "New Device" ,
121- is_active = True
126+ # is_active=True # Sesuaikan dengan model kamu
122127 )
123128 db .add (new_device )
124129 db .commit ()
125- db .refresh (new_device )
126130
127- return {"message" : f"Sukses! Alat { clean_id } berhasil didaftarkan otomatis ." }
131+ return {"message" : f"Sukses! Alat { clean_id } didaftarkan." }
0 commit comments