Pengusir-Hama-Burung-Otomatis/project/tugas_akhir/lib/screens/kontrol_page.dart

305 lines
9.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:tugas_akhir/screens/notifikasi_page.dart';
import 'dart:async';
import '../services/notif_service.dart';
/// 🔥 GLOBAL
String globalLastStatus = "";
DateTime? lastNotifTime;
class KontrolPage extends StatefulWidget {
const KontrolPage({super.key});
@override
State<KontrolPage> createState() => _KontrolPageState();
}
class _KontrolPageState extends State<KontrolPage> {
bool isManual = false;
late DatabaseReference db;
StreamSubscription<DatabaseEvent>? modeSubscription;
StreamSubscription<DatabaseEvent>? deteksiSubscription;
@override
void initState() {
super.initState();
db = FirebaseDatabase.instanceFor(
app: Firebase.app(),
databaseURL:
"https://tugas-akhir-9947b-default-rtdb.asia-southeast1.firebasedatabase.app",
).ref();
// =================================================
// MODE MANUAL
// =================================================
modeSubscription = db.child("kontrol/mode").onValue.listen((event) {
final data = event.snapshot.value;
print("MODE DATA: $data");
if (data != null && mounted) {
setState(() {
isManual = data.toString() == "1";
});
}
});
// =================================================
// STATUS / NOTIFIKASI
// =================================================
deteksiSubscription = db.child("Kebun/Status").onValue.listen((event) {
final data = event.snapshot.value;
if (data == null) return;
String status = data.toString().trim().toLowerCase();
print("STATUS: $status");
// =============================================
// NOTIF HANYA SAAT BAHAYA
// =============================================
if (status == "bahaya" && !isManual) {
bool bolehNotif = false;
if (lastNotifTime == null) {
bolehNotif = true;
} else {
final selisih = DateTime.now().difference(lastNotifTime!);
if (selisih.inSeconds > 15) {
bolehNotif = true;
}
}
if (bolehNotif) {
lastNotifTime = DateTime.now();
NotifService.showNotif(
"⚠️ Hama Burung!",
"Burung terdeteksi di kebun",
);
}
}
globalLastStatus = status;
});
}
@override
void dispose() {
modeSubscription?.cancel();
deteksiSubscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
"Kontrol Alat",
style: TextStyle(color: Colors.white),
),
backgroundColor: const Color(0xFF6FCF97),
iconTheme: const IconThemeData(color: Colors.white),
actions: [
IconButton(
icon: const Icon(Icons.notifications),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const NotifikasiPage()),
);
},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// =========================================
// MODE SWITCH
// =========================================
Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: const Color(0xFFBFD8C6),
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("Mode Manual"),
Switch(
value: isManual,
onChanged: (value) async {
await db.child("kontrol/mode").set(value ? 1 : 0);
},
),
],
),
),
const SizedBox(height: 30),
const Text(
"Kontrol Perangkat",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 15),
Row(
children: [
// =====================================
// SERVO -> SEKARANG: GERAKAN
// =====================================
Expanded(
child: GestureDetector(
onTap: isManual
? () async {
await db.child("kontrol/servo").set(1);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Servo Aktif")),
);
}
: null,
child: Container(
height: 100,
decoration: BoxDecoration(
color: isManual
? const Color(0xFF6FCF97)
: Colors.grey.shade400,
borderRadius: BorderRadius.circular(12),
boxShadow: isManual
? [
BoxShadow(
color: Colors.black12,
blurRadius: 4,
offset: const Offset(0, 2),
),
]
: [],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.screen_rotation_alt_rounded,
color: isManual
? Colors.white
: Colors.grey.shade600,
size: 32,
),
const SizedBox(height: 8),
Text(
"GERAKAN",
style: TextStyle(
color: isManual
? Colors.white
: Colors.grey.shade600,
fontWeight: FontWeight.bold,
letterSpacing: 1.2,
),
),
],
),
),
),
),
const SizedBox(width: 16),
// =====================================
// BUZZER -> SEKARANG: SUARA
// =====================================
Expanded(
child: GestureDetector(
onTap: isManual
? () async {
await db.child("kontrol/buzzer").set(1);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Buzzer Aktif")),
);
}
: null,
child: Container(
height: 100,
decoration: BoxDecoration(
color: isManual
? const Color(0xFF6FCF97)
: Colors.grey.shade400,
borderRadius: BorderRadius.circular(12),
boxShadow: isManual
? [
BoxShadow(
color: Colors.black12,
blurRadius: 4,
offset: const Offset(0, 2),
),
]
: [],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.volume_up_rounded,
color: isManual
? Colors.white
: Colors.grey.shade600,
size: 32,
),
const SizedBox(height: 8),
Text(
"SUARA",
style: TextStyle(
color: isManual
? Colors.white
: Colors.grey.shade600,
fontWeight: FontWeight.bold,
letterSpacing: 1.2,
),
),
],
),
),
),
),
],
),
],
),
),
);
}
}