TKK_E32230206/lib/services/api_control_service.dart

141 lines
4.6 KiB
Dart

import 'package:dio/dio.dart';
import '../core/api_config.dart';
/// Layanan Klien untuk mengirimkan instruksi kontrol hardware (ESP32) ke API Backend.
/// Menangani pemanggilan REST API untuk: pengaturan mode (Auto/Manual), threshold, penyiraman manual, dan penjadwalan.
class ApiControlService {
final Dio _dio;
final String deviceId;
ApiControlService(this.deviceId, [Dio? dio]) : _dio = dio ?? Dio();
// ── Mode Operasi ─────────────────────────────────────────────
/// Mengambil mode operasi perangkat saat ini dari backend.
Future<String> getMode() async {
try {
final res = await _dio.get('${ApiConfig.baseUrl}/mode/$deviceId');
if (res.statusCode == 200 && res.data != null) {
return res.data['current_mode'] ?? 'auto';
}
return 'auto';
} catch (e) {
return 'auto';
}
}
/// Mengubah mode operasi perangkat (Otomatis/Manual) di server.
Future<void> setMode(String mode) async {
try {
await _dio.post(
'${ApiConfig.baseUrl}/mode/$deviceId',
data: {'mode': mode},
);
} catch (e) {
throw Exception('Gagal mengubah mode: $e');
}
}
/// Mengambil nilai batas threshold sensor suhu dan kelembapan saat ini.
Future<Map<String, dynamic>> getThreshold() async {
try {
final res = await _dio.get('${ApiConfig.baseUrl}/threshold/$deviceId');
if (res.statusCode == 200 && res.data != null) {
return res.data;
}
throw Exception('Gagal memuat threshold');
} catch (e) {
throw Exception('Error: $e');
}
}
/// Memperbarui nilai batas threshold suhu ([tempMax]) dan kelembapan ([humMax]) di server.
Future<void> updateThreshold(double tempMax, double humMax) async {
try {
await _dio.post(
'${ApiConfig.baseUrl}/threshold/$deviceId',
data: {
'temp_max': tempMax,
'hum_max': humMax,
},
);
} catch (e) {
throw Exception('Gagal update threshold: $e');
}
}
// ── Manual Control (Pompa) ───────────────────────────────────
/// Mengirimkan instruksi menyalakan pompa secara instan selama [durationSeconds] detik.
Future<void> siramManual(int durationSeconds) async {
try {
await _dio.post(
'${ApiConfig.baseUrl}/schedule/$deviceId/now',
data: {'duration_s': durationSeconds},
);
} catch (e) {
throw Exception('Gagal menyalakan pompa: $e');
}
}
/// Menghentikan aktivitas pompa secara instan (mematikan pompa).
Future<void> stopPump() async {
try {
await _dio.post('${ApiConfig.baseUrl}/schedule/$deviceId/stop');
} catch (e) {
throw Exception('Gagal mematikan pompa: $e');
}
}
// ── Schedules (Jadwal) ───────────────────────────────────────
/// Mengambil daftar semua jadwal penyiraman otomatis yang terdaftar untuk perangkat ini.
Future<List<dynamic>> getSchedules() async {
try {
final res = await _dio.get('${ApiConfig.baseUrl}/schedule/$deviceId');
if (res.statusCode == 200 && res.data != null) {
return res.data as List<dynamic>;
}
return [];
} catch (e) {
throw Exception('Gagal memuat jadwal: $e');
}
}
/// Menambahkan jadwal penyiraman baru ke backend.
/// [cron] format string cron UTC, [durationSeconds] durasi siram, [label] penanda nama jadwal.
Future<Map<String, dynamic>> addSchedule(String cron, int durationSeconds, String label) async {
try {
final res = await _dio.post(
'${ApiConfig.baseUrl}/schedule/$deviceId',
data: {
'cron': cron,
'duration_s': durationSeconds,
'label': label,
},
);
if (res.statusCode == 200 || res.statusCode == 201) {
return res.data;
}
throw Exception('Gagal menambah jadwal');
} catch (e) {
throw Exception('Error tambah jadwal: $e');
}
}
/// Menghapus jadwal tertentu berdasarkan ID.
Future<void> deleteSchedule(String id) async {
try {
await _dio.delete('${ApiConfig.baseUrl}/schedule/$id');
} catch (e) {
throw Exception('Gagal menghapus jadwal: $e');
}
}
/// Mengaktifkan atau menonaktifkan saklar jadwal tertentu (toggle status is_active).
Future<void> toggleSchedule(String id) async {
try {
await _dio.patch('${ApiConfig.baseUrl}/schedule/$id/toggle');
} catch (e) {
throw Exception('Gagal toggle jadwal: $e');
}
}
}