Skip to content

Commit 91b85b3

Browse files
committed
Add control relay schema and enhance control relay endpoint with dynamic topic handling
1 parent 003d21f commit 91b85b3

2 files changed

Lines changed: 54 additions & 17 deletions

File tree

app/api/v1/devices.py

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class DeviceResponse(BaseModel):
4040

4141
class Config:
4242
from_attributes = True
43+
44+
class ControlRelaySchema(BaseModel):
45+
relay_name: str # relay_1, relay_2, relay_3
46+
state: bool # true = ON, false = OFF
4347

4448
# ==========================================
4549
# 2. ENDPOINTS
@@ -145,33 +149,57 @@ def unclaim_device(
145149

146150
# --- E. CONTROL RELAY ---
147151
# Limit: 20 request / menit (Biar bisa on/off agak cepat)
148-
@router.post("/control-relay", dependencies=[Depends(RateLimiter(times=20, seconds=60))])
152+
@router.post("/control-relay", dependencies=[Depends(RateLimiter(times=30, seconds=60))])
149153
def control_relay(
150154
device_id: str,
151-
state: str,
155+
# Kita terima data sebagai Query Parameters biar sama kayak request Flutter
156+
relay_name: str,
157+
state: bool,
152158
db: Session = Depends(get_db),
153159
user_uid: str = Depends(get_current_user) # 🔒 Wajib Login
154160
):
155161
clean_id = device_id.strip().upper()
156-
157-
if state not in ["ON", "OFF"]:
158-
return {"error": "State harus ON atau OFF"}
159-
162+
163+
# 1. Validasi Alat & Kepemilikan
160164
device = db.query(Device).filter(Device.device_id == clean_id).first()
161-
162165
if not device:
163166
raise HTTPException(status_code=404, detail="Alat tidak ditemukan.")
164-
167+
165168
if device.owner_uid != user_uid:
166-
raise HTTPException(status_code=403, detail="Eits! Bukan alat kamu.")
167-
168-
topic = f"alat/{clean_id}/command"
169-
payload = f'{{"relay": "{state}"}}'
169+
raise HTTPException(status_code=403, detail="Bukan alat kamu!")
170170

171-
mqtt_client.publish(topic, payload)
171+
# 2. Konversi State (Boolean -> String MQTT)
172+
payload_str = "ON" if state else "OFF"
172173

173-
return {"message": "Perintah dikirim", "topic": topic, "state": state}
174+
# 3. Mapping Topik (Sesuaikan dengan Kode ESP32)
175+
# relay_1 = Lampu
176+
# relay_2 = Kipas Exhaust (Ganti jadi Pompa Minum kalau di ESP32 pakai Pompa)
177+
# relay_3 = Pompa Air
178+
179+
topic_suffix = ""
180+
if relay_name == "relay_1":
181+
topic_suffix = "lampu"
182+
elif relay_name == "relay_2":
183+
topic_suffix = "pompa_minum" # Asumsi relay_2 adalah pompa minum
184+
elif relay_name == "relay_3":
185+
topic_suffix = "pompa_siram" # Asumsi relay_3 adalah pompa siram
186+
else:
187+
raise HTTPException(status_code=400, detail="Relay name tidak valid (relay_1/2/3)")
188+
189+
# 4. Rakit Topik Akhir
190+
# Format: alat/{ID}/cmd/{SUFFIX}
191+
mqtt_topic = f"alat/{clean_id}/cmd/{topic_suffix}"
192+
193+
# 5. Kirim ke Broker
194+
mqtt_client.publish(mqtt_topic, payload_str)
195+
196+
print(f"🐍 [PYTHON] MQTT Publish -> {mqtt_topic}: {payload_str}")
174197

198+
return {
199+
"status": "success",
200+
"message": f"Perintah {payload_str} dikirim ke {topic_suffix}",
201+
"topic": mqtt_topic
202+
}
175203

176204
# --- F. AUTO REGISTER (Mesin ke Mesin) ---
177205
# Limit: 5 request / menit

app/schemas/log.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@ class LogBase(BaseModel):
66
topic_type: str
77
value: str
88

9-
# Cetakan untuk Response API (ditambah ID & Waktu)
10-
class LogResponse(LogBase):
9+
class LogResponse(BaseModel):
1110
id: int
1211
device_id: str
12+
temperature: float
13+
humidity: float
14+
amonia: float
15+
feed_level: float
16+
17+
# Tambahkan status relay ini
18+
relay_1: bool # Lampu
19+
relay_2: bool # Kipas/Pompa Minum
20+
relay_3: bool # Pompa Siram
21+
1322
created_at: datetime
1423

1524
class Config:
16-
from_attributes = True # Supaya bisa baca data dari SQLAlchemy
25+
from_attributes = True

0 commit comments

Comments
 (0)