TKK_E32210055/lib/home/home_view.dart

543 lines
15 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:google_fonts/google_fonts.dart';
import 'package:inkubator/login.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:inkubator/theme.dart';
class HomeView extends StatefulWidget {
final String espIpAddress;
HomeView({required this.espIpAddress});
@override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
final TextEditingController _dayController = TextEditingController();
String _response = '';
double temperature = 0.0;
double humidity = 0.0;
int _day = 0;
int _sec = 0;
Timer? _timer;
Timer? _dataTimer;
@override
void initState() {
super.initState();
_fetchCurrentTime();
_fetchSensorData();
_startTimer();
}
@override
void dispose() {
_timer?.cancel();
_dataTimer?.cancel();
super.dispose();
}
void _startTimer() {
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
_sec++;
if (_sec >= 3600) {
_fetchCurrentTime();
_fetchSensorData();
}
});
});
_dataTimer = Timer.periodic(Duration(seconds: 2), (timer) {
_fetchSensorData();
});
}
Future<void> _fetchCurrentTime() async {
try {
final response =
await http.get(Uri.parse('http://${widget.espIpAddress}/'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
setState(() {
_day = data['day'];
_sec = data['hours'] * 3600 + data['minutes'] * 60 + data['seconds'];
});
} else {
setState(() {
_response = 'Failed to connect: ${response.statusCode}';
});
}
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
Future<void> _fetchSensorData() async {
try {
final response =
await http.get(Uri.parse('http://${widget.espIpAddress}/dht'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
setState(() {
temperature = data['temperature'];
humidity = data['humidity'];
});
} else {
setState(() {
_response = 'Failed to connect: ${response.statusCode}';
});
}
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
Future<void> _sendTimeToESP() async {
final url = 'http://${widget.espIpAddress}/';
Map<String, dynamic> data = {
'day': int.parse(_dayController.text),
};
try {
final response = await http.post(
Uri.parse(url),
headers: {"Content-Type": "application/json"},
body: json.encode(data),
);
if (response.statusCode == 200) {
_fetchCurrentTime();
Navigator.of(context).pop(); // Close the dialog on success
} else {
setState(() {
_response = 'Failed to connect: ${response.statusCode}';
});
}
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
Future<void> _powerOn() async {
final response = await http.post(
Uri.parse('http://${widget.espIpAddress}/inkubator'),
headers: {"Content-Type": "application/json"},
body: '{"inkubator": "on"}',
);
if (response.statusCode == 200) {
print('Power On');
_showSnackbar('Power On Successful');
} else {
print('Failed to Power On');
_showSnackbar('Failed to Power On');
}
}
Future<void> _powerOff() async {
final response = await http.post(
Uri.parse('http://${widget.espIpAddress}/inkubator'),
headers: {"Content-Type": "application/json"},
body: '{"inkubator": "off"}',
);
if (response.statusCode == 200) {
print('Power Off');
_showSnackbar('Power Off Successful');
} else {
print('Failed to Power Off');
_showSnackbar('Power Off Successful');
}
}
void _showSnackbar(String message) {
final snackBar = SnackBar(
content: Text(message),
duration: Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
Future<void> _showDayInputDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Set Elapsed Day'),
content: TextField(
controller: _dayController,
keyboardType: TextInputType.number,
decoration: InputDecoration(hintText: "Enter new elapsed day"),
),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Set'),
onPressed: _sendTimeToESP,
),
],
);
},
);
}
void _logout() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('espIpAddress');
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => LoginView()),
);
}
int parseTime(String time) {
List<String> parts = time.split(' ');
_day = int.parse(parts[0]);
List<String> timeParts = parts[1].split(':');
int hours = int.parse(timeParts[0]);
int minutes = int.parse(timeParts[1]);
int seconds = int.parse(timeParts[2]);
return (hours * 3600 + minutes * 60 + seconds);
}
Widget countDown() {
int hours = _sec ~/ 3600;
int minutes = (_sec % 3600) ~/ 60;
int seconds = _sec % 60;
String dayStr = _day.toString().padLeft(2, '0');
String hoursStr = hours.toString().padLeft(2, '0');
String minutesStr = minutes.toString().padLeft(2, '0');
String secondsStr = seconds.toString().padLeft(2, '0');
return Center(
child: Container(
margin: EdgeInsets.only(top: 36),
height: 100,
width: 400,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 1,
offset: Offset(0, 1),
),
],
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Day: $dayStr',
style: GoogleFonts.spaceMono(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.black),
),
Text(
'$hoursStr:$minutesStr:$secondsStr',
style: GoogleFonts.spaceMono(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.black),
),
],
),
),
),
);
}
Widget Power() {
return Center(
child: Container(
margin: EdgeInsets.only(top: 36),
height: 100,
width: 400,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 1,
offset: Offset(0, 1),
),
],
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Power",
style: GoogleFonts.spaceMono(fontSize: 18),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _powerOn,
child: Text('Power On'),
style: ElevatedButton.styleFrom(fixedSize: Size(120, 40)),
),
SizedBox(
width: 20,
),
ElevatedButton(
onPressed: _powerOff,
child: Text('Power Off'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.redAccent,
fixedSize: Size(120, 40)),
),
],
),
],
),
),
),
);
}
Widget title() {
return Container(
margin: EdgeInsets.only(top: 22),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Suhu dan Kelembapan",
style: GoogleFonts.spaceMono(fontSize: 18),
),
Container(
child: Text(
"",
style: GoogleFonts.spaceMono(
color: Colors.redAccent,
fontWeight: FontWeight.bold,
),
),
)
],
),
);
}
Widget temperature1() {
return Container(
width: double.infinity,
margin: EdgeInsets.only(top: 8),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 1,
offset: Offset(0, 1),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 2,
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Container(
height: 60,
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFFF6DBDB),
borderRadius: BorderRadius.circular(15),
image: DecorationImage(
image: AssetImage('assets/images/suhu.png'),
),
),
),
),
),
SizedBox(width: 12),
Expanded(
flex: 6,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Suhu',
style: GoogleFonts.spaceMono(fontSize: 18),
),
Text(
'${temperature.toStringAsFixed(2)} °C',
style: GoogleFonts.spaceMono(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
Divider(color: Colors.grey),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 2,
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Container(
height: 60,
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFFE2F2F5),
borderRadius: BorderRadius.circular(15),
image: DecorationImage(
image: AssetImage('assets/images/kelembapan.png'),
),
),
),
),
),
SizedBox(width: 12),
Expanded(
flex: 6,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Kelembapan',
style: GoogleFonts.spaceMono(fontSize: 18),
),
Text(
'${humidity.toStringAsFixed(2)} %',
style: GoogleFonts.spaceMono(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
],
),
);
}
// Widget tombol() {
// return Container(
// width: double.infinity,
// // height: 250,
// margin: EdgeInsets.only(top: 8),
// padding: EdgeInsets.all(8),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(15),
// color: Colors.white,
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.5),
// blurRadius: 1,
// offset: Offset(0, 1), // changes position of shadow
// ),
// ],
// ),
// child: Column(
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// 'Kontrol Alat',
// style: primaryTextStyle.copyWith(fontSize: 18),
// ),
// TextButton(
// onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => KontrolView(
// espIpAddress: widget.espIpAddress,
// ),
// ));
// },
// child: Text('Buka')),
// ],
// ),
// ],
// ),
// );
// }
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.black),
elevation: 0,
backgroundColor: Colors.black,
automaticallyImplyLeading: false,
centerTitle: true,
title: Text(
"Home",
style: secondaryTextStyle.copyWith(fontSize: 16),
),
actions: [
IconButton(
icon: Icon(Icons.edit),
color: Colors.white,
onPressed: _showDayInputDialog,
),
SizedBox(
width: 3,
),
IconButton(
onPressed: _logout,
icon: Icon(Icons.logout_rounded),
color: Colors.white,
)
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: ListView(
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
Power(),
countDown(),
title(),
temperature1(),
],
),
),
);
}
}