mirror of
https://github.com/0015/ThatProject.git
synced 2026-01-12 09:17:42 +03:00
ESP32 | FLUTTER | FIREBASE - Temperature & Humidity Check App
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CircleProgress extends CustomPainter {
|
||||
double value;
|
||||
bool isTemp;
|
||||
|
||||
CircleProgress(this.value, this.isTemp);
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
int maximumValue =
|
||||
isTemp ? 50 : 100; // Temp's max is 50, Humidity's max is 100
|
||||
|
||||
Paint outerCircle = Paint()
|
||||
..strokeWidth = 14
|
||||
..color = Colors.grey
|
||||
..style = PaintingStyle.stroke;
|
||||
|
||||
Paint tempArc = Paint()
|
||||
..strokeWidth = 14
|
||||
..color = Colors.red
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeCap = StrokeCap.round;
|
||||
|
||||
Paint humidityArc = Paint()
|
||||
..strokeWidth = 14
|
||||
..color = Colors.blue
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeCap = StrokeCap.round;
|
||||
|
||||
Offset center = Offset(size.width / 2, size.height / 2);
|
||||
double radius = min(size.width / 2, size.height / 2) - 14;
|
||||
canvas.drawCircle(center, radius, outerCircle);
|
||||
|
||||
double angle = 2 * pi * (value / maximumValue);
|
||||
|
||||
canvas.drawArc(Rect.fromCircle(center: center, radius: radius), -pi / 2,
|
||||
angle, false, isTemp ? tempArc : humidityArc);
|
||||
}
|
||||
}
|
||||
180
Esp32_Flutter_firebase_DHT/esp32_firebase/lib/Dashboard.dart
Normal file
180
Esp32_Flutter_firebase_DHT/esp32_firebase/lib/Dashboard.dart
Normal file
@@ -0,0 +1,180 @@
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_database/firebase_database.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
import 'package:rflutter_alert/rflutter_alert.dart';
|
||||
|
||||
import 'CircleProgress.dart';
|
||||
import 'main.dart';
|
||||
|
||||
class Dashboard extends StatefulWidget {
|
||||
@override
|
||||
_DashboardState createState() => _DashboardState();
|
||||
}
|
||||
|
||||
class _DashboardState extends State<Dashboard>
|
||||
with SingleTickerProviderStateMixin {
|
||||
bool isLoading = false;
|
||||
final GoogleSignIn googleSignIn = GoogleSignIn();
|
||||
|
||||
final databaseReference = FirebaseDatabase.instance.reference();
|
||||
|
||||
AnimationController progressController;
|
||||
Animation<double> tempAnimation;
|
||||
Animation<double> humidityAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
databaseReference
|
||||
.child('ESP32_Device')
|
||||
.once()
|
||||
.then((DataSnapshot snapshot) {
|
||||
double temp = snapshot.value['Temperature']['Data'];
|
||||
double humidity = snapshot.value['Humidity']['Data'];
|
||||
|
||||
isLoading = true;
|
||||
_DashboardInit(temp, humidity);
|
||||
});
|
||||
}
|
||||
|
||||
_DashboardInit(double temp, double humid) {
|
||||
progressController = AnimationController(
|
||||
vsync: this, duration: Duration(milliseconds: 5000)); //5s
|
||||
|
||||
tempAnimation =
|
||||
Tween<double>(begin: -50, end: temp).animate(progressController)
|
||||
..addListener(() {
|
||||
setState(() {});
|
||||
});
|
||||
|
||||
humidityAnimation =
|
||||
Tween<double>(begin: 0, end: humid).animate(progressController)
|
||||
..addListener(() {
|
||||
setState(() {});
|
||||
});
|
||||
|
||||
progressController.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Dashboard'),
|
||||
centerTitle: true,
|
||||
automaticallyImplyLeading: false,
|
||||
leading: new IconButton(
|
||||
icon: Icon(Icons.reorder), onPressed: handleLoginOutPopup),
|
||||
),
|
||||
body: Center(
|
||||
child: isLoading
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
CustomPaint(
|
||||
foregroundPainter:
|
||||
CircleProgress(tempAnimation.value, true),
|
||||
child: Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('Temperature'),
|
||||
Text(
|
||||
'${tempAnimation.value.toInt()}',
|
||||
style: TextStyle(
|
||||
fontSize: 50, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'°C',
|
||||
style: TextStyle(
|
||||
fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
CustomPaint(
|
||||
foregroundPainter:
|
||||
CircleProgress(humidityAnimation.value, false),
|
||||
child: Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('Humidity'),
|
||||
Text(
|
||||
'${humidityAnimation.value.toInt()}',
|
||||
style: TextStyle(
|
||||
fontSize: 50, fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'%',
|
||||
style: TextStyle(
|
||||
fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
'Loading...',
|
||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
handleLoginOutPopup() {
|
||||
Alert(
|
||||
context: context,
|
||||
type: AlertType.info,
|
||||
title: "Login Out",
|
||||
desc: "Do you want to login out now?",
|
||||
buttons: [
|
||||
DialogButton(
|
||||
child: Text(
|
||||
"No",
|
||||
style: TextStyle(color: Colors.white, fontSize: 20),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
color: Colors.teal,
|
||||
),
|
||||
DialogButton(
|
||||
child: Text(
|
||||
"Yes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 20),
|
||||
),
|
||||
onPressed: handleSignOut,
|
||||
color: Colors.teal,
|
||||
)
|
||||
],
|
||||
).show();
|
||||
}
|
||||
|
||||
Future<Null> handleSignOut() async {
|
||||
this.setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
await FirebaseAuth.instance.signOut();
|
||||
await googleSignIn.signOut();
|
||||
|
||||
this.setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(builder: (context) => MyApp()),
|
||||
(Route<dynamic> route) => false);
|
||||
}
|
||||
}
|
||||
98
Esp32_Flutter_firebase_DHT/esp32_firebase/lib/main.dart
Normal file
98
Esp32_Flutter_firebase_DHT/esp32_firebase/lib/main.dart
Normal file
@@ -0,0 +1,98 @@
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
|
||||
import 'Dashboard.dart';
|
||||
|
||||
void main() => runApp(MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'ESP32 Temp & humid App',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.teal,
|
||||
),
|
||||
home: LoginScreen(title: 'ESP32 Temp & humid App'),
|
||||
debugShowCheckedModeBanner: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
final String title;
|
||||
|
||||
LoginScreen({Key key, this.title}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LoginScreenState createState() => _LoginScreenState();
|
||||
}
|
||||
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
|
||||
|
||||
GoogleSignIn _googleSignIn = GoogleSignIn(
|
||||
scopes: <String>['email'],
|
||||
);
|
||||
|
||||
GoogleSignInAccount _currentUser;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) {
|
||||
setState(() {
|
||||
_currentUser = account;
|
||||
});
|
||||
|
||||
if (_currentUser != null) {
|
||||
_handleFirebase();
|
||||
}
|
||||
});
|
||||
|
||||
_googleSignIn.signInSilently(); //Auto login if previous login was success
|
||||
}
|
||||
|
||||
void _handleFirebase() async {
|
||||
GoogleSignInAuthentication googleAuth = await _currentUser.authentication;
|
||||
|
||||
final AuthCredential credential = GoogleAuthProvider.getCredential(
|
||||
idToken: googleAuth.idToken, accessToken: googleAuth.accessToken);
|
||||
|
||||
final FirebaseUser firebaseUser =
|
||||
await firebaseAuth.signInWithCredential(credential);
|
||||
|
||||
if (firebaseUser != null) {
|
||||
print('Login');
|
||||
|
||||
Navigator.of(context).pushReplacement(
|
||||
new MaterialPageRoute(builder: (context) => new Dashboard()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handleSignIn() async {
|
||||
try {
|
||||
await _googleSignIn.signIn();
|
||||
} catch (error) {
|
||||
print(error);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: Center(
|
||||
child: FlatButton(
|
||||
onPressed: _handleSignIn,
|
||||
child: Text('Google Sign in'),
|
||||
color: Colors.amber,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user