import 'package:flutter/material.dart'; import 'package:firebase_database/firebase_database.dart'; import 'setpoint_screen.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { final DatabaseReference dbRef = FirebaseDatabase.instance.ref("hydroponic/monitoring"); final DatabaseReference controlRef = FirebaseDatabase.instance.ref("hydroponic/control"); double ph = 0.0; double ppm = 0.0; int waterAir = 0; int waterAbmix = 0; int waterPHUp = 0; int waterPHDown = 0; bool relayAir = false; bool relayNutrisi = false; bool relayPhUp = false; bool relayPhDown = false; String statusPh = "-"; String statusTds = "-"; String wifiStatus = "-"; String mode = "AUTO"; @override void initState() { super.initState(); print("Firebase path: ${dbRef.path}"); dbRef.onValue.listen( (event) { print("===== FIREBASE EVENT ====="); print(event.snapshot.value); if (event.snapshot.value == null) { print("DATA NULL"); return; } try { final data = Map.from(event.snapshot.value as Map); setState(() { ph = double.tryParse(data['ph'].toString()) ?? 0.0; ppm = double.tryParse(data['ppm'].toString()) ?? 0.0; waterAir = data['water_air'] ?? 0; waterAbmix = data['water_abmix'] ?? 0; waterPHUp = data['water_ph_up'] ?? 0; waterPHDown = data['water_ph_down'] ?? 0; relayAir = data['relay_air'] ?? false; relayNutrisi = data['relay_nutrisi'] ?? false; relayPhUp = data['relay_ph_up'] ?? false; relayPhDown = data['relay_ph_down'] ?? false; statusPh = data['status_ph']?.toString() ?? "-"; statusTds = data['status_tds']?.toString() ?? "-"; wifiStatus = data['wifi_status']?.toString() ?? "-"; }); print("PH = $ph"); print("PPM = $ppm"); print("STATUS PH = $statusPh"); print("STATUS TDS = $statusTds"); } catch (e) { print("ERROR FIREBASE: $e"); } }, onError: (error) { print("FIREBASE ERROR:"); print(error); }, ); controlRef.onValue.listen((event) { if (event.snapshot.value == null) return; try { final data = Map.from(event.snapshot.value as Map); setState(() { mode = data['mode']?.toString() ?? "AUTO"; relayAir = data['relay_air'] ?? false; relayNutrisi = data['relay_nutrisi'] ?? false; relayPhUp = data['relay_ph_up'] ?? false; relayPhDown = data['relay_ph_down'] ?? false; }); print("MODE = $mode"); } catch (e) { print("CONTROL ERROR: $e"); } }); } Widget sensorCard( String title, String value, String status, Color color, ) { return Card( elevation: 5, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ CircleAvatar( radius: 35, backgroundColor: color, child: Text( value, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16, ), ), ), const SizedBox(width: 15), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 18, ), ), const SizedBox(height: 5), Text( status, style: TextStyle( color: color, fontWeight: FontWeight.bold, ), ), ], ), ), ], ), ), ); } Widget statusRow( IconData icon, String title, bool status, ) { return Card( elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), child: ListTile( leading: Icon( icon, color: status ? Colors.green : Colors.grey, ), title: Text( title, style: const TextStyle( fontWeight: FontWeight.w600, ), ), trailing: Chip( backgroundColor: status ? Colors.green : Colors.red, label: Text( status ? "ON" : "OFF", style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ), ); } Widget manualButton( String title, String firebaseKey, bool currentValue, ) { return Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), child: SwitchListTile( title: Text( title, style: const TextStyle( fontWeight: FontWeight.w600, ), ), value: currentValue, activeColor: Colors.green, onChanged: (value) async { await controlRef .child(firebaseKey) .set(value); }, ), ); } String getWaterLevelWarning() { List warningList = []; if (waterAir < 1000) { warningList.add("Tangki Air Bersih"); } if (waterAbmix < 1000) { warningList.add("Tangki AB Mix"); } if (waterPHUp < 1000) { warningList.add("Tangki pH Up"); } if (waterPHDown < 1000) { warningList.add("Tangki pH Down"); } return warningList.join(", "); } @override Widget build(BuildContext context) { final phColor = (ph >= 5.5 && ph <= 6.5) ? Colors.green : Colors.red; final ppmColor = (ppm >= 800 && ppm <= 1100) ? Colors.green : Colors.orange; return Scaffold( appBar: AppBar( title: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.eco), SizedBox(width: 8), Text("Eco Green House"), ], ), centerTitle: true, backgroundColor: Colors.green, actions: [ IconButton( icon: const Icon(Icons.settings), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SetpointScreen(), ), ); }, ), ], ), body: ListView( padding: const EdgeInsets.all(12), children: [ if ( waterAir < 1000 || waterAbmix < 1000 || waterPHUp < 1000 || waterPHDown < 1000 ) Container( margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.all(15), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(15), ), child: Row( children: [ const Icon( Icons.warning, color: Colors.white, ), const SizedBox(width: 10), Expanded( child: Text( "${getWaterLevelWarning()} rendah, segera isi tangki!", style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ], ), ), Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(20), ), child: Column( children: [ const Icon( Icons.eco, color: Colors.white, size: 60, ), const SizedBox(height: 10), const Text( "Eco Green House", style: TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 5), Text( "WiFi : $wifiStatus", style: const TextStyle( color: Colors.white, ), ), ], ), ), const SizedBox(height: 15), Row( children: [ Expanded( child: Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ const Icon( Icons.science, color: Colors.blue, size: 35, ), const SizedBox(height: 8), const Text( "pH", style: TextStyle( fontWeight: FontWeight.bold, ), ), Text( ph.toStringAsFixed(2), style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, ), ), ], ), ), ), ), Expanded( child: Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ const Icon( Icons.water_drop, color: Colors.green, size: 35, ), const SizedBox(height: 8), const Text( "PPM", style: TextStyle( fontWeight: FontWeight.bold, ), ), Text( ppm.toStringAsFixed(0), style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, ), ), ], ), ), ), ), ], ), Card( child: ListTile( title: const Text("Mode Sistem"), subtitle: Text("Status: $mode"), trailing: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: mode == "AUTO" ? Colors.green : Colors.orange, ), onPressed: () { final newMode = mode == "AUTO" ? "MANUAL" : "AUTO"; controlRef.child("mode").set(newMode); }, child: Text( mode == "AUTO" ? "Switch MANUAL" : "Switch AUTO", ), ), ), ), if (mode == "MANUAL") ...[ manualButton("Pompa Air", "relay_air", relayAir), manualButton("Pompa Nutrisi", "relay_nutrisi", relayNutrisi), manualButton("Pompa pH Up", "relay_ph_up", relayPhUp), manualButton("Pompa pH Down", "relay_ph_down", relayPhDown), const SizedBox(height: 10), ], statusRow( Icons.arrow_upward, "Pompa pH Up", relayPhUp, ), statusRow( Icons.arrow_downward, "Pompa pH Down", relayPhDown, ), statusRow( Icons.eco, "Pompa Nutrisi", relayNutrisi, ), statusRow( Icons.water_drop, "Pompa Air", relayAir, ), Card( child: ListTile( leading: const Icon(Icons.wifi), title: const Text("WiFi Status"), trailing: Text( wifiStatus, style: TextStyle( color: wifiStatus == "connected" ? Colors.green : Colors.red, fontWeight: FontWeight.bold, ), ), ), ), ], ), ); } }