feat(frontend): fecth and display sensor data
This commit is contained in:
parent
d42b840b18
commit
ee1a7102cb
@ -1,7 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'sensor_provider.dart';
|
||||||
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (context) => SensorProvider(),
|
||||||
|
child: const MyApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
@ -10,30 +18,28 @@ class MyApp extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Flutter Demo',
|
title: 'Sensor App',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
primarySwatch: Colors.blue,
|
||||||
),
|
),
|
||||||
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
home: const SensorScreen(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
class SensorScreen extends StatefulWidget {
|
||||||
const MyHomePage({super.key, required this.title});
|
const SensorScreen({super.key});
|
||||||
|
|
||||||
final String title;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MyHomePage> createState() => _MyHomePageState();
|
_SensorScreenState createState() => _SensorScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _SensorScreenState extends State<SensorScreen> {
|
||||||
int _counter = 0;
|
@override
|
||||||
|
void initState() {
|
||||||
void _incrementCounter() {
|
super.initState();
|
||||||
setState(() {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_counter++;
|
Provider.of<SensorProvider>(context, listen: false).fetchData();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,25 +47,37 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
title: const Text('Mercury'),
|
||||||
title: Text(widget.title),
|
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Consumer<SensorProvider>(
|
||||||
|
builder: (context, sensorProvider, child) {
|
||||||
|
if (sensorProvider.sensorData == null) {
|
||||||
|
if (sensorProvider.error != null) {
|
||||||
|
return Text('Error: ${sensorProvider.error}');
|
||||||
|
}
|
||||||
|
return const CircularProgressIndicator();
|
||||||
|
} else {
|
||||||
|
final data = sensorProvider.sensorData!;
|
||||||
|
final timeAgo = timeago.format(DateTime.fromMillisecondsSinceEpoch(data.timestamp));
|
||||||
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: [
|
||||||
const Text('You have pushed the button this many times:'),
|
Text('🌡️ Temperature: ${data.temperature}°C'),
|
||||||
Text(
|
Text('💧 Humidity: ${data.humidity}%'),
|
||||||
'$_counter',
|
Text('❄️ Dew Point: ${data.dewPoint}°C'),
|
||||||
style: Theme.of(context).textTheme.headlineMedium,
|
Text('🕒 $timeAgo'),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: _incrementCounter,
|
onPressed: () {
|
||||||
tooltip: 'Increment',
|
Provider.of<SensorProvider>(context, listen: false).fetchData();
|
||||||
child: const Icon(Icons.add),
|
},
|
||||||
|
child: const Icon(Icons.refresh),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
22
mercury_frontend/lib/sensor_data.dart
Normal file
22
mercury_frontend/lib/sensor_data.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
class SensorData {
|
||||||
|
final double temperature;
|
||||||
|
final double humidity;
|
||||||
|
final double dewPoint;
|
||||||
|
final int timestamp;
|
||||||
|
|
||||||
|
SensorData({
|
||||||
|
required this.temperature,
|
||||||
|
required this.humidity,
|
||||||
|
required this.dewPoint,
|
||||||
|
required this.timestamp,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SensorData.fromJson(Map<String, dynamic> json) {
|
||||||
|
return SensorData(
|
||||||
|
temperature: json['temperature'],
|
||||||
|
humidity: json['humidity'],
|
||||||
|
dewPoint: json['dewPoint'],
|
||||||
|
timestamp: json['timestamp'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
mercury_frontend/lib/sensor_provider.dart
Normal file
23
mercury_frontend/lib/sensor_provider.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'sensor_data.dart';
|
||||||
|
import 'sensor_service.dart';
|
||||||
|
|
||||||
|
class SensorProvider with ChangeNotifier {
|
||||||
|
final SensorService _service = SensorService();
|
||||||
|
SensorData? _sensorData;
|
||||||
|
|
||||||
|
Error? _error;
|
||||||
|
|
||||||
|
SensorData? get sensorData => _sensorData;
|
||||||
|
|
||||||
|
Error? get error => _error;
|
||||||
|
|
||||||
|
Future<void> fetchData() async {
|
||||||
|
try {
|
||||||
|
_sensorData = await _service.fetchSensorData();
|
||||||
|
} catch (e) {
|
||||||
|
_error = e as Error;
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
17
mercury_frontend/lib/sensor_service.dart
Normal file
17
mercury_frontend/lib/sensor_service.dart
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'sensor_data.dart';
|
||||||
|
|
||||||
|
class SensorService {
|
||||||
|
final String url = 'https://mercury.segin.one/sensor';
|
||||||
|
|
||||||
|
Future<SensorData> fetchSensorData() async {
|
||||||
|
final response = await http.get(Uri.parse(url));
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
return SensorData.fromJson(json.decode(response.body));
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load sensor data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -75,6 +75,30 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
http:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
intl:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.19.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -131,6 +155,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0"
|
version: "1.16.0"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -139,6 +171,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
provider:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.2"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -192,6 +232,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.4"
|
version: "0.7.4"
|
||||||
|
timeago:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: timeago
|
||||||
|
sha256: "054cedf68706bb142839ba0ae6b135f6b68039f0b8301cbe8784ae653d5ff8de"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.7.0"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -208,6 +264,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.3.1"
|
version: "14.3.1"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.7.0 <4.0.0"
|
dart: ">=3.7.0 <4.0.0"
|
||||||
flutter: ">=3.18.0-18.0.pre.54"
|
flutter: ">=3.18.0-18.0.pre.54"
|
||||||
|
|||||||
@ -34,6 +34,9 @@ dependencies:
|
|||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
|
provider: ^6.1.2
|
||||||
|
http: ^1.3.0
|
||||||
|
timeago: ^3.7.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user