ESP32 | FLUTTER | FIREBASE - Temperature & Humidity Check App

This commit is contained in:
Eric
2019-07-22 00:40:06 -07:00
parent a4597ab575
commit e8b26483f5
65 changed files with 2895 additions and 0 deletions

View File

@@ -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);
}
}

View 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);
}
}

View 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,
),
),
);
}
}